Skip to content

Commit 702beb3

Browse files
committed
Merge branch 'cc/bisect'
* cc/bisect: Documentation: remove warning saying that "git bisect skip" may slow bisection bisect: use a PRNG with a bias when skipping away from untestable commits
2 parents a4103ba + 32d86ca commit 702beb3

File tree

3 files changed

+43
-16
lines changed

3 files changed

+43
-16
lines changed

Documentation/git-bisect.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,8 @@ to do it for you by issuing the command:
164164
$ git bisect skip # Current version cannot be tested
165165
------------
166166

167-
But computing the commit to test may be slower afterwards and git may
168-
eventually not be able to tell the first bad commit among a bad commit
169-
and one or more skipped commits.
167+
But git may eventually be unable to tell the first bad commit among
168+
a bad commit and one or more skipped commits.
170169

171170
You can even skip a range of commits, instead of just one commit,
172171
using the "'<commit1>'..'<commit2>'" notation. For example:

bisect.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -585,16 +585,49 @@ struct commit_list *filter_skipped(struct commit_list *list,
585585
return filtered;
586586
}
587587

588-
static struct commit_list *apply_skip_ratio(struct commit_list *list,
589-
int count,
590-
int skip_num, int skip_denom)
588+
#define PRN_MODULO 32768
589+
590+
/*
591+
* This is a pseudo random number generator based on "man 3 rand".
592+
* It is not used properly because the seed is the argument and it
593+
* is increased by one between each call, but that should not matter
594+
* for this application.
595+
*/
596+
int get_prn(int count) {
597+
count = count * 1103515245 + 12345;
598+
return ((unsigned)(count/65536) % PRN_MODULO);
599+
}
600+
601+
/*
602+
* Custom integer square root from
603+
* http://en.wikipedia.org/wiki/Integer_square_root
604+
*/
605+
static int sqrti(int val)
606+
{
607+
float d, x = val;
608+
609+
if (val == 0)
610+
return 0;
611+
612+
do {
613+
float y = (x + (float)val / x) / 2;
614+
d = (y > x) ? y - x : x - y;
615+
x = y;
616+
} while (d >= 0.5);
617+
618+
return (int)x;
619+
}
620+
621+
static struct commit_list *skip_away(struct commit_list *list, int count)
591622
{
592-
int index, i;
593623
struct commit_list *cur, *previous;
624+
int prn, index, i;
625+
626+
prn = get_prn(count);
627+
index = (count * prn / PRN_MODULO) * sqrti(prn) / sqrti(PRN_MODULO);
594628

595629
cur = list;
596630
previous = NULL;
597-
index = count * skip_num / skip_denom;
598631

599632
for (i = 0; cur; cur = cur->next, i++) {
600633
if (i == index) {
@@ -614,7 +647,6 @@ static struct commit_list *managed_skipped(struct commit_list *list,
614647
struct commit_list **tried)
615648
{
616649
int count, skipped_first;
617-
int skip_num, skip_denom;
618650

619651
*tried = NULL;
620652

@@ -626,11 +658,7 @@ static struct commit_list *managed_skipped(struct commit_list *list,
626658
if (!skipped_first)
627659
return list;
628660

629-
/* Use alternatively 1/5, 2/5 and 3/5 as skip ratio. */
630-
skip_num = count % 3 + 1;
631-
skip_denom = 5;
632-
633-
return apply_skip_ratio(list, count, skip_num, skip_denom);
661+
return skip_away(list, count);
634662
}
635663

636664
static void bisect_rev_setup(struct rev_info *revs, const char *prefix,

t/t6030-bisect-porcelain.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,8 +563,8 @@ test_expect_success 'skipping away from skipped commit' '
563563
hash7=$(git rev-parse --verify HEAD) &&
564564
test "$hash7" = "$HASH7" &&
565565
git bisect skip &&
566-
hash3=$(git rev-parse --verify HEAD) &&
567-
test "$hash3" = "$HASH3"
566+
para3=$(git rev-parse --verify HEAD) &&
567+
test "$para3" = "$PARA_HASH3"
568568
'
569569

570570
#

0 commit comments

Comments
 (0)