@matheusbsbs / matheus-bagliano / commits / 9f199b1595
Fork 0

rev-list: estimate number of bisection step left

This patch teaches "git rev-list --bisect-vars" to output an estimate of the number of bisection step left _after the current one_ along with the other variables it already outputs. This patch also makes "git-bisect.sh" display this number of steps left _after the current one_, along with the estimate of the number of revisions left to test (after the current one). Here is a table to help analyse what should be the best estimate for the number of bisect steps left. N : linear case --> probabilities --> best ------------------------------------------------------------- 1 : G-B --> 0 --> 0 2 : G-U1-B --> 0 --> 0 3 : G-U1-U2-B --> 0(1/3) 1(2/3) --> 1 4 : G-U1-U2-U3-B --> 1 --> 1 5 : G-U1-U2-U3-U4-B --> 1(3/5) 2(2/5) --> 1 6 : G-U1-U2-U3-U4-U5-B --> 1(2/6) 2(4/6) --> 2 7 : G-U1-U2-U3-U4-U5-U6-B --> 1(1/7) 2(6/7) --> 2 8 : G-U1-U2-U3-U4-U5-U6-U7-B --> 2 --> 2 9 : G-U1-U2-U3-U4-U5-U6-U7-U8-B --> 2(7/9) 3(2/9) --> 2 10: G-U1-U2-U3-U4-U5-U6-U7-U8-U9-B --> 2(6/10)3(4/10)--> 2 In the column "N", there is the number of revisions that could _now_ be the first bad commit we are looking for. The "linear case" column describes the linear history corresponding to the number in column N. G means good, B means bad, and Ux means unknown. Note that the first bad revision we are looking for can be any Ux or B. In the "probabilities" column, there are the different outcomes in number of steps with the odds of each outcome in parenthesis corresponding to the linear case. The "best" column gives the most accurate estimate among the different outcomes in the "probabilities" column. We have the following: best(2^n) == n - 1 and for any x between 0 included and 2^n excluded, the probability for n - 1 steps left looks like: P(2^n + x) == (2^n - x) / (2^n + x) and P(2^n + x) < 0.5 means 2^n < 3x So the algorithm used in this patch calculates 2^n and x, and then choose between returning n - 1 and n. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Feb 21, 2009 at 09:26 UTC 9f199b159580545c39716fd87038f8ff7cd0eace
2 files changed +44 -3
builtin-rev-list.c
+43 -2
@@ -574,6 +574,45 @@ static struct commit_list *find_bisection(struct commit_list *list,
574 return best;
575 }
576
577 +static inline int log2i(int n)
578 +{
579 + int log2 = 0;
580 +
581 + for (; n > 1; n >>= 1)
582 + log2++;
583 +
584 + return log2;
585 +}
586 +
587 +static inline int exp2i(int n)
588 +{
589 + return 1 << n;
590 +}
591 +
592 +/*
593 + * Estimate the number of bisect steps left (after the current step)
594 + *
595 + * For any x between 0 included and 2^n excluded, the probability for
596 + * n - 1 steps left looks like:
597 + *
598 + * P(2^n + x) == (2^n - x) / (2^n + x)
599 + *
600 + * and P(2^n + x) < 0.5 means 2^n < 3x
601 + */
602 +static int estimate_bisect_steps(int all)
603 +{
604 + int n, x, e;
605 +
606 + if (all < 3)
607 + return 0;
608 +
609 + n = log2i(all);
610 + e = exp2i(n);
611 + x = all - e;
612 +
613 + return (e < 3 * x) ? n : n - 1;
614 +}
615 +
616 int cmd_rev_list(int argc, const char **argv, const char *prefix)
617 {
618 struct commit_list *list;
@@ -688,12 +727,14 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
727 "bisect_nr=%d\n"
728 "bisect_good=%d\n"
729 "bisect_bad=%d\n"
691 - "bisect_all=%d\n",
730 + "bisect_all=%d\n"
731 + "bisect_steps=%d\n",
732 hex,
733 cnt - 1,
734 all - reaches - 1,
735 reaches - 1,
696 - all);
736 + all,
737 + estimate_bisect_steps(all));
738 return 0;
739 }
740 }
git-bisect.sh
+1 -1
@@ -512,7 +512,7 @@ bisect_next() {
512 # commit is also a "skip" commit (see above).
513 exit_if_skipped_commits "$bisect_rev"
514
515 - bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this"
515 + bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this (roughly $bisect_steps steps)"
516 }
517
518 bisect_visualize() {