bisect: when skipping, choose a commit away from a skipped commit
authorChristian Couder <chriscool@tuxfamily.org>
Sat, 6 Jun 2009 04:41:34 +0000 (06:41 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sat, 6 Jun 2009 18:26:56 +0000 (11:26 -0700)
To do that a new function "apply_skip_ratio" is added and another
function "managed_skipped" is created to wrap both "filter_skipped"
and the previous one.

In "managed_skipped" we detect when we should choose a commit away
from a skipped one and then we automatically choose a skip ratio
to pass to "apply_skip_ratio".

The ratio is choosen so that it alternates between 1/5, 2/5 and
3/5.

In "apply_skip_ratio", we ignore a given ratio of all the commits
that could be tested.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
bisect.c

index 115cf5fa41d91c047ee2081bf0d22cb6ae638970..6fdff05722c3afa8e8e4cdcac200697e4116ea8e 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -585,6 +585,54 @@ struct commit_list *filter_skipped(struct commit_list *list,
        return filtered;
 }
 
+static struct commit_list *apply_skip_ratio(struct commit_list *list,
+                                           int count,
+                                           int skip_num, int skip_denom)
+{
+       int index, i;
+       struct commit_list *cur, *previous;
+
+       cur = list;
+       previous = NULL;
+       index = count * skip_num / skip_denom;
+
+       for (i = 0; cur; cur = cur->next, i++) {
+               if (i == index) {
+                       if (hashcmp(cur->item->object.sha1, current_bad_sha1))
+                               return cur;
+                       if (previous)
+                               return previous;
+                       return list;
+               }
+               previous = cur;
+       }
+
+       return list;
+}
+
+static struct commit_list *managed_skipped(struct commit_list *list,
+                                          struct commit_list **tried)
+{
+       int count, skipped_first;
+       int skip_num, skip_denom;
+
+       *tried = NULL;
+
+       if (!skipped_revs.sha1_nr)
+               return list;
+
+       list = filter_skipped(list, tried, 0, &count, &skipped_first);
+
+       if (!skipped_first)
+               return list;
+
+       /* Use alternatively 1/5, 2/5 and 3/5 as skip ratio. */
+       skip_num = count % 3 + 1;
+       skip_denom = 5;
+
+       return apply_skip_ratio(list, count, skip_num, skip_denom);
+}
+
 static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
                             const char *bad_format, const char *good_format,
                             int read_paths)
@@ -897,7 +945,7 @@ int bisect_next_all(const char *prefix)
 
        revs.commits = find_bisection(revs.commits, &reaches, &all,
                                       !!skipped_revs.sha1_nr);
-       revs.commits = filter_skipped(revs.commits, &tried, 0, NULL, NULL);
+       revs.commits = managed_skipped(revs.commits, &tried);
 
        if (!revs.commits) {
                /*