You know, that you can use git-bisect to search for changes in your git-repository history that introduced a bug, do you? I did but I never got the chance to try it out ..until this morning. If you have no idea what it is or how it works, check its excellent, super self-explaining, man-page. But, depending on your project and how you can test a specific revision for the problem, this bug-hunt can take a really long time.
Bisect run
But wait, we’re in luck. git-bisect comes with a handy “run” command that allows you to automate this procedure. So instead of checking each revision manually we can tell Bisect to do it for us. Here is how:
$ git bisect run script arguments
Bisect’s run command instruments a script that should return 0 if the current revision is good and something between 1 and 127 (except 125, which indicates that the revision should be skipped) if its bad. But wait, how could a script identify that damn bug, that broke everything and nobody knows where it hides itself?!
Write a spec
Of course! You need to write a spec around your broken feature. And it should happily fail. The last missing part of our bug-hunt-soup is a spec runner. A script that runs your spec (file) and returns the appropriate exit codes. RSpec’s runner, for example, is capable of doing that kind of stuff. Using rspec, it should look something like that:
$ git bisect run spec bug_spec.rb
Putting the pieces together
Ok. So we got a clever tool that hunts through your git-repository-history and a script that tells us if a specific revision is broken (bad) or not (good).
$ git bisect start HEAD <commit> —
$ git bisect run spec bug_spec.rb
The first command tells Bisect which range of revisions it should use. HEAD is a “bad” one, <commit> points to a good revision (e.g. the revision where a certain feature was added). The second command starts the hunt..
Try it out
I’ve created a github repository that includes some test files, you can use to play around with Bisect and RSpec. At first, you should have a look at the repo’s Readme.. Done? Alright lets play:
The resulting output is or should be “-5”, which is wrong as you can see in the code snippet below. Somebody broke the sum method somewhere in the code’s history. You’re right. This “math” thing is a really lame example, but it should be ok for explaining and playing git-bisect.
Ok. Let’s finally find the revision that introduced the bug:
The resulting output should tell you that
857c26b4193e57adfd11c312f3ad8b7c723565a0 is the first bad commit
Yeah!