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.

How binary search works.

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.

Happy bisecting!

Picture credits