Cut your way through problems with git bisect
We (developers) write bug-free code and it’s always “someone else” who introduces a bug that is found too late, usually when software doesn’t work on a different environment. It’s especially painful if the one to find the problem is – you. If only one change was made and it was working before, then it’s easy. But what if you had 10, 100 or even 1000 changes (revisions)?
When the problem is obscure and you can’t pinpoint it, the way to a solution is going back in history and checking which revision introduced it. The quickest way of doing that is a binary search. If you have one hundred new revisions you’ll want to go to the first (earliest) one and check for the problem. If everything works, you will confirm it’s somewhere in between the first and the last one. Then you jump to the middle and test again. If OK, then it must be towards the end; if not, it was earlier. Then you jump to the middle of the smaller suspicious section and repeat the process until you find the problematic revision.
If you’re working with Git, it has a very nice command that will help you immensely in the above mentioned process –
git bisect. The way it works is that you tell Git if the current revision is good or bad and it calculates the next jump and checkouts the revision preparing the working copy for you to test it.
If we take the example above you would position to the 100th revision and write:
git bisect start git bisect bad
This starts the process and marks that the current revision is not working. Go to the first one (that is working) and type:
git bisect good
At this moment Git will jump to the middle of the range, write the number of revisions left and approximate number of steps needed to cover them all. In this case we would have 98 more revisions to test and it would take roughly 7 steps (log2 98 for those who like math).
You have to “rate” every revision with
git bisect good/bad until you find the one that introduced a bug. To check out the current status and the history of bisecting, use
git bisect log. If you have gitk installed, you can visualize the log with
git bisect visualize.
When you’re finished, run
git bisect reset
for Git to return you to the place you’ve started from.
There are few more time and nerve saving tricks
git bisect has and you should read
git help bisect if you’re interested. One of those is
git bisect run. If you have a script that can tell if the current revision is good or bad, you can use that command to automatically run through all revisions.