Bisecting pathological code with Git

Sometimes, you end up with a bug in the code base and have no clue
where that bug was introduced...

Git has a "bisect" functionality that helps you determine which commit
introduced the pathology.

Once you've found where the problem lies, then Git can't replace your
worthy talent to fix it in the most elegant way human can think
of. Hey, your genius can't be cloned into a program (yet).

So here are the steps to follow when trying to use "git bisect" to
isolate the faulty commit that is responsible for breaking the feature
you've put so much time and effort implementing.

Using Git to help you

Now you wonder how Git can help you isolate the faulty commit, the
all-evil one that brought your program in regression? Here you go...

First step

Make sure you have a way, ideally systematic (read programmatic) to
make checks on the expected results. Having a script or a
semi-automatic way of proceeding might be very useful since you want
to have reproducible results easily, painlessly, reproduce these
results a given number of times.

The theory of complexity says that if you have N items among which to
proceed with a binary search, then you have roughly ceiling(log(N))
steps towards finding what you're looking for.

In practice, this may lead to about 10 iterations. So if you're as
lazy as I am, you'll want to automate the checking from iteration to

Second step

To start the bisection search, and it's really a binary search among a
set of commits, you need to identify two edge commits, i.e. one where
it fails (usually the "HEAD" of the branch you're working on) and one
where the feature was working fine. These are the boundaries within
which the binary search will be made.

Third step

Now you can start using Git for the search. It can be initiated using the following command:

git bisect start

You have to tell bisect what are the boundaries of the search. You indicate the commit that is faulty by issuing the following command:

git bisect bad

Leaving the commit hash empty will tell Git to use the HEAD.
You indicate the commit where the functionality is working fine by
issuing the following command: 

git bisect good

From now on, Git will proceed by identifying the median commit in the
search space, check it out and let you proceed with the testing to
identify if the functionality is good/bad.

You can tell Git about that by issuing

git bisect good


git bisect bad


Final step

Once you're done, you can stop the "bisect" functionality with this
git bisect reset

Further readings

You can see these web pages for further details:


No comments:

Post a Comment