diff options
-rw-r--r-- | Documentation/git-bisect.txt | 5 | ||||
-rw-r--r-- | bisect.c | 50 | ||||
-rwxr-xr-x | t/t6030-bisect-porcelain.sh | 4 |
3 files changed, 43 insertions, 16 deletions
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index ffc02c737c..63e7a42cb3 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -164,9 +164,8 @@ to do it for you by issuing the command: $ git bisect skip # Current version cannot be tested ------------ -But computing the commit to test may be slower afterwards and git may -eventually not be able to tell the first bad commit among a bad commit -and one or more skipped commits. +But git may eventually be unable to tell the first bad commit among +a bad commit and one or more skipped commits. You can even skip a range of commits, instead of just one commit, using the "'<commit1>'..'<commit2>'" notation. For example: @@ -585,16 +585,49 @@ 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) +#define PRN_MODULO 32768 + +/* + * This is a pseudo random number generator based on "man 3 rand". + * It is not used properly because the seed is the argument and it + * is increased by one between each call, but that should not matter + * for this application. + */ +int get_prn(int count) { + count = count * 1103515245 + 12345; + return ((unsigned)(count/65536) % PRN_MODULO); +} + +/* + * Custom integer square root from + * http://en.wikipedia.org/wiki/Integer_square_root + */ +static int sqrti(int val) +{ + float d, x = val; + + if (val == 0) + return 0; + + do { + float y = (x + (float)val / x) / 2; + d = (y > x) ? y - x : x - y; + x = y; + } while (d >= 0.5); + + return (int)x; +} + +static struct commit_list *skip_away(struct commit_list *list, int count) { - int index, i; struct commit_list *cur, *previous; + int prn, index, i; + + prn = get_prn(count); + index = (count * prn / PRN_MODULO) * sqrti(prn) / sqrti(PRN_MODULO); cur = list; previous = NULL; - index = count * skip_num / skip_denom; for (i = 0; cur; cur = cur->next, i++) { if (i == index) { @@ -614,7 +647,6 @@ 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; @@ -626,11 +658,7 @@ static struct commit_list *managed_skipped(struct commit_list *list, 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); + return skip_away(list, count); } static void bisect_rev_setup(struct rev_info *revs, const char *prefix, diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 4556cdd8d2..1315bab595 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -563,8 +563,8 @@ test_expect_success 'skipping away from skipped commit' ' hash7=$(git rev-parse --verify HEAD) && test "$hash7" = "$HASH7" && git bisect skip && - hash3=$(git rev-parse --verify HEAD) && - test "$hash3" = "$HASH3" + para3=$(git rev-parse --verify HEAD) && + test "$para3" = "$PARA_HASH3" ' # |