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
This commit is contained in:
Junio C Hamano
2009-07-01 19:41:04 -07:00
3 changed files with 43 additions and 16 deletions

View File

@ -164,9 +164,8 @@ to do it for you by issuing the command:
$ git bisect skip # Current version cannot be tested $ git bisect skip # Current version cannot be tested
------------ ------------
But computing the commit to test may be slower afterwards and git may But git may eventually be unable to tell the first bad commit among
eventually not be able to tell the first bad commit among a bad commit a bad commit and one or more skipped commits.
and one or more skipped commits.
You can even skip a range of commits, instead of just one commit, You can even skip a range of commits, instead of just one commit,
using the "'<commit1>'..'<commit2>'" notation. For example: using the "'<commit1>'..'<commit2>'" notation. For example:

View File

@ -585,16 +585,49 @@ struct commit_list *filter_skipped(struct commit_list *list,
return filtered; return filtered;
} }
static struct commit_list *apply_skip_ratio(struct commit_list *list, #define PRN_MODULO 32768
int count,
int skip_num, int skip_denom) /*
* 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; 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; cur = list;
previous = NULL; previous = NULL;
index = count * skip_num / skip_denom;
for (i = 0; cur; cur = cur->next, i++) { for (i = 0; cur; cur = cur->next, i++) {
if (i == index) { if (i == index) {
@ -614,7 +647,6 @@ static struct commit_list *managed_skipped(struct commit_list *list,
struct commit_list **tried) struct commit_list **tried)
{ {
int count, skipped_first; int count, skipped_first;
int skip_num, skip_denom;
*tried = NULL; *tried = NULL;
@ -626,11 +658,7 @@ static struct commit_list *managed_skipped(struct commit_list *list,
if (!skipped_first) if (!skipped_first)
return list; return list;
/* Use alternatively 1/5, 2/5 and 3/5 as skip ratio. */ return skip_away(list, count);
skip_num = count % 3 + 1;
skip_denom = 5;
return apply_skip_ratio(list, count, skip_num, skip_denom);
} }
static void bisect_rev_setup(struct rev_info *revs, const char *prefix, static void bisect_rev_setup(struct rev_info *revs, const char *prefix,

View File

@ -563,8 +563,8 @@ test_expect_success 'skipping away from skipped commit' '
hash7=$(git rev-parse --verify HEAD) && hash7=$(git rev-parse --verify HEAD) &&
test "$hash7" = "$HASH7" && test "$hash7" = "$HASH7" &&
git bisect skip && git bisect skip &&
hash3=$(git rev-parse --verify HEAD) && para3=$(git rev-parse --verify HEAD) &&
test "$hash3" = "$HASH3" test "$para3" = "$PARA_HASH3"
' '
# #