Browse Source

Merge branch 'sg/bisect-approximately-halfway'

"git bisect start/next" in a large span of history spends a lot of
time trying to come up with exactly the half-way point; this can be
optimized by stopping when we see a commit that is close enough to
the half-way point.

* sg/bisect-approximately-halfway:
  bisect: loosen halfway() check for a large number of commits
maint
Junio C Hamano 4 years ago
parent
commit
2557c1183a
  1. 27
      bisect.c

27
bisect.c

@ -103,8 +103,10 @@ static int count_interesting_parents(struct commit *commit, unsigned bisect_flag @@ -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) @@ -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, @@ -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, @@ -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;
}
}

Loading…
Cancel
Save