git bisect is amazing. You don’t know what it is? Let me fill you in!
git bisect is a tool that allows you to find an offending commit. Let’s say you’ve come across a bug in your codebase and you’re unsure of when it was introduced. If you can find a commit where the code works properly and a commit where it doesn’t, you don’t have to trace down the offending commit by hand; git-bisect will do that for you.
In my situation, the test suite did not actually catch the bug. It was a design flaw, so I had to find it by hand. So how do I find out where the bug was introduced?
git bisect has a manual mode which works perfectly in this situation.
# start up git bisect git bisect start # give git a commit where there is not a bug git bisect good a09c728 # give git a commit where there is a bug git bisect bad b6a0692
At this point git is going to start splitting the revisions in half and loading them up for you. It will checkout each revision and then ask you if the commit is good or bad. You answer
git bisect good or
git bisect bad and git will take care of the rest. It will use binary search to very quickly narrow down the offending commit.
The number of revisions you have between your “good” and “bad commits” will determine how long this process takes but it will still be quicker than individually checking out each commit.
Manually finding bugs with bisect is great but we can also automate it. You can pass any script to git bisect and have it check that script against each commit within the revision list. The script should end with a non-zero return status when it fails. Your test suite already does this so if you have a failing test, this is easy.
# get it ready git bisect start git bisect good c09c728 git bisect bad e6a0692 # give git a command to run against each commit git bisect run rspec spec/features/my_broken_spec.rb
The same process will happen as before only git will handle the whole process for you. It will checkout each revision, run the command and record its response. Within a few minutes, git will show you the offending commit. The only downside is when you find a commit with your name on it!
Do you have any awesome git tricks? Tell us about it on Twitter.