SyntaxHighlighter

2012/05/16

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
iteration.

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


or


git bisect bad


accordingly.

Final step

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

Further readings

You can see these web pages for further details:

  • http://git-scm.com/book/en/Git-Tools-Debugging-with-Git#Binary-Search 
  • http://webchick.net/node/99 


No comments:

Post a Comment