Introduction to Git Bisect
"git bisect" can be a little confusing at first. Once you understand what it does, it'll be easy.
The typical scenerio for "git bisect" is: A bug was just discovered. You want to find out which rev introduced the bug. You know the bug exists in the latest rev, but it was introduced in a prior rev. You will need a way to find out whether or not the bug exists. This can be an automatic test, or it can be a test you run by hand.
Let's get started. Starting from the latest rev in your branch, issue:
git bisect start
And then tell git that the current version is known to be good:
git bisect bad
Now we need to find a bad rev. Check one something old enough to not have the bug. If you think that 32 revs ago ought to be good, then:
git checkout HEAD~32
And run your test to see if it has the bug. If it has the bug, you'll need to try an even older rev (just issue "git checkout HEAD~32" again). As soon as you land on a rev that does not have the bug, then:
git bisect good
That tells git that the current version is good. Git will immediately check out a rev in-between the good rev and the bad rev; you'll see output, for example:
$ git bisect good
Bisecting: 7 revisions left to test after this (roughly 3 steps)
[909ba8cd7698720d00b2d10738f6d970a8955be4] Added convenience delegators to Cache
Run your test, and depending upon the results of the test, issue one of these commands:
git bisect good # the test passed
git bisect bad # the test failed
git bisect skip # we can't run the test on this rev for some reason
(doesn't compile, etc.)
Git will continue to change to different revs, and you'll keep telling it good, bad or skip. When git finally figures out which rev started all the trouble, you'll get something like this:
b25ab3cee963f4738264c9c9b5a8d1a344a94623 is the first bad commit
commit b25ab3cee963f4738264c9c9b5a8d1a344a94623
Author: Wayne Conrad <[email protected]>
Date: Fri Dec 25 18:20:54 2009 -0700
More tests and refactoring
:040000 040000 6ff7502d5828598af55c7517fd9626ba019b16aa 39f346cb5a289cdb0955fcbba552f40e704b7e65 M routecalc
And your current rev will be there, on the first bad commit.
Running git bisect "hands off"
If your test is automatic, then you can let git do all the work. Do everything you did to get started above:
git bisect start
git bisect bad
git checkout HEAD~32 # or however far back it takes to find a good rev
git bisect good
And now for the magic. All you need is a test program that returns exit code "0" for success and 1 (for example) for failure. Tell git about your test:
git bisect run tests/mytest.rb
Git will now run the test, using the results to automatically do a "git bisect good" or a "git bisect bad." It will continue doing that until the first bad rev is found. All you have to do is sit back and watch.
When you're done
When you're done, issue:
git bisect reset
Git will put you back where you started.