How to git bisect skip choose the next commit to try?

When using git bisect you can run git bisect skip to mark the current commit as unset / unchecked, to try to get Git, to select a different commit to check.

How to git bisect skip decide which fix to try after git bisect skip ? The experiment shows that this is not only an adjacent fix, but I cannot work out a pattern.

Change I know that the basic git bisect is a binary search, but I'm curious about git bisect skip , which obviously makes something more complicated.

The experiment shows that he does not just choose adjacent fixation; below, 100 commits are created with the number 0 - 99, then their division begins in half. The first git bisect latch is selected in the middle, but each git bisect skip after that seems more or less random.

 $ git init Initialized empty Git repository in .git/ $ for (( i=0; i<100; i++ )); do echo $i > file; git add file; git commit -m $i >/dev/null; done # Create some dummy commits $ git bisect start HEAD $(git rev-list --max-parents=0 HEAD) # HEAD is bad, root commit is good. Bisecting: 49 revisions left to test after this (roughly 6 steps) [099e5cf2ccde625f92dc369da6cad0bdf2852ce4] 49 $ git bisect skip Bisecting: 49 revisions left to test after this (roughly 6 steps) [88c8208a7c4322222124167e49f07c741af7d3d8] 60 $ git bisect skip Bisecting: 49 revisions left to test after this (roughly 6 steps) [04695f2e5b2473c3ac72435c0dbfc3ba1375abda] 88 $ git bisect skip Bisecting: 49 revisions left to test after this (roughly 6 steps) [1e9bf3d29589bcac2d8c467245ae8d446c195252] 40 $ git bisect skip Bisecting: 49 revisions left to test after this (roughly 6 steps) [9459ed79e4112d674681c8f0f921127217c7ebc6] 13 
+14
git git-bisect
source share
2 answers

I rummaged a bit in the source code of Git and found most of the answer myself ...

Starting with Git v1.6.4 (specifically with the ebc9529f commit ), Git uses the “PRNG (pseudo random number generator) offset” to determine which commit should be made next after skipping.

I can’t say that I follow the algorithm itself (which, starting from v2.8.1, it seems that it has not been fundamentally affected since it was first added), but the commit message does a reasonable job explaining what happens:

bisect: use slanted PRNG when skipping untested commits

Using a PRNG (pseudo-random number generator) with an offset should be better than alternating three fixed ratios.

In repositories with a large number of unchecked commits, this should prevent the alternation of areas where many commits are unchecked. The offset should give preference to commits, which can provide more information so that the process of halving does not lose its effectiveness.

HPA proposed using PRNG and found that the best bias is to increase the ratio between 0 and 1 given by PRNG to a power of 1.5.

So it looks like Git is picking the next commit for a random attempt, but a random distribution has been chosen to (hopefully) select commits that provide more information for binary search, and avoid commits that might be in areas of unchecked commits.

+19
source share

As the name Git suggests, the short answer is: This is not your business .

The idea of git bisect is that you specify two endpoints and Git appears in it, for example, a commit, which, in its opinion, is useful for reducing the number of tests.

As the documentation says, this is just a binary search, but does not indicate which algorithm is used

Git bisect then selects a fix between these two endpoints

It may not be a simple pick-the-middle-commit binary search, Git can use any solution algorithm that it wants, and it obviously doesn’t want you to know it, so you don’t make assumptions about the commit that will be raised.

When it comes to changing the assembled commit, it gives you two options:

  • You manually select a new commit. For example, using git reset --hard .
  • You will tell Git to make a new choice, git bisect skip .

In the latter case, when you update the endpoints with good and bad , the decision is made by Git as he wants.


Out of curiosity, I made a simple single-interface repository and tried the git bisect skip command.
My version of Git took a previous commit.

-7
source share

All Articles