Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

git-bisect

When using git bisect, one can run git bisect skip to mark the current commit as being an unbuildable / untestable one, to try and get Git to pick some other commit to test instead.

How does Git decide which commit to try after a git bisect skip? Experimenting shows it's not just an adjacent commit, but I can't work out the pattern.

Edit: I'm aware the basic git bisect is a binary search, but I'm curious about git bisect skip, which is clearly doing something more complicated.

Experimentation shows it's not just picking an adjacent commit; the below creates 100 commits numbered 0–99 then starts bisecting them. The first commit git bisect picks is in the middle, but each git bisect skip thereafter seems to be more-or-less randomly selected.

$ 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 
like image 224
me_and Avatar asked Apr 08 '16 10:04

me_and


People also ask

How does git bisect work?

git bisect performs a binary search to find the faulty commit. Git bisect requires the user to input the “good” commit and the “bad” commit, and then performs a binary search on the commits, starting with the commit that is at the midpoint between the “good” and “bad” commit.

How do I remove a bad commit in git bisect?

Use git log to check the previous commits. Use Git Bisect to find the commit in which line 2 is changed from 'b = 20' to 'b = 0.00000'. Remove the bad commit by using Git Revert. Leave the commit message as is.

What is git bisect how can you use it to determine the source of a regression bug?

The git bisect command is a fantastic tool that can help you determine which commit introduced the bug. A regression bug is a specific type of software bug that prevents a feature or software from working when it was working before the bug was introduced. Just remember, git bisect won't "fix" the broken commit for you.


1 Answers

I did some digging into the Git source code and found most of an answer myself...

As of Git v1.6.4 (specifically, as of commit ebc9529f), Git uses "a PRNG (pseudo random number generator) with a bias" to determine which commit to try next after skipping one.

I can't say I follow the algorithm itself (which, as of v2.8.1, appears to be fundamentally untouched since it was first added), but the commit message does a reasonable job of explaining what's going on:

bisect: use a PRNG with a bias when skipping away from untestable commits

Using a PRNG (pseudo random number generator) with a bias should be better than alternating between 3 fixed ratios.

In repositories with many untestable commits it should prevent alternating between areas where many commits are untestable. The bias should favor commits that can give more information, so that the bisection process should not loose much efficiency.

HPA suggested to use a PRNG and found that the best bias is to raise a ratio between 0 and 1 given by the PRNG to the power 1.5.

So it looks as though Git picks the next commit to try at random, but the random distribution was picked to (hopefully) choose commits that give more information for the binary search and to avoid commits likely to be in regions of untestable commits.

like image 162
me_and Avatar answered Sep 30 '22 19:09

me_and