summaryrefslogtreecommitdiff
path: root/bisect.c
diff options
context:
space:
mode:
Diffstat (limited to 'bisect.c')
-rw-r--r--bisect.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/bisect.c b/bisect.c
index f5b1368128..d8c2c8f7a7 100644
--- a/bisect.c
+++ b/bisect.c
@@ -103,8 +103,10 @@ static int count_interesting_parents(struct commit *commit, unsigned bisect_flag
return count;
}
-static inline int halfway(struct commit_list *p, int nr)
+static inline int approx_halfway(struct commit_list *p, int nr)
{
+ int diff;
+
/*
* Don't short-cut something we are not going to return!
*/
@@ -113,13 +115,22 @@ static inline int halfway(struct commit_list *p, int nr)
if (DEBUG_BISECT)
return 0;
/*
- * 2 and 3 are halfway of 5.
+ * For small number of commits 2 and 3 are halfway of 5, and
* 3 is halfway of 6 but 2 and 4 are not.
*/
- switch (2 * weight(p) - nr) {
+ diff = 2 * weight(p) - nr;
+ switch (diff) {
case -1: case 0: case 1:
return 1;
default:
+ /*
+ * For large number of commits we are not so strict, it's
+ * good enough if it's within ~0.1% of the halfway point,
+ * e.g. 5000 is exactly halfway of 10000, but we consider
+ * the values [4996, 5004] as halfway as well.
+ */
+ if (abs(diff) < nr / 1024)
+ return 1;
return 0;
}
}
@@ -321,8 +332,9 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
weight_set(p, count_distance(p));
clear_distance(list);
- /* Does it happen to be at exactly half-way? */
- if (!(bisect_flags & FIND_BISECTION_ALL) && halfway(p, nr))
+ /* Does it happen to be at half-way? */
+ if (!(bisect_flags & FIND_BISECTION_ALL) &&
+ approx_halfway(p, nr))
return p;
counted++;
}
@@ -362,8 +374,9 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
else
weight_set(p, weight(q));
- /* Does it happen to be at exactly half-way? */
- if (!(bisect_flags & FIND_BISECTION_ALL) && halfway(p, nr))
+ /* Does it happen to be at half-way? */
+ if (!(bisect_flags & FIND_BISECTION_ALL) &&
+ approx_halfway(p, nr))
return p;
}
}
@@ -1090,7 +1103,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
nr), nr, steps_msg);
free(steps_msg);
/* Clean up objects used, as they will be reused. */
- clear_commit_marks_all(ALL_REV_FLAGS);
+ repo_clear_commit_marks(r, ALL_REV_FLAGS);
return bisect_checkout(bisect_rev, no_checkout);
}