Once in a while, there is a need to track that one single commit that silently slipped into the codebase breaking it. The obvious brute-force solution of consecutively reverting the repository commit by commit may not always be the best. Finding a commit that may be far away in history usually becomes tedious and time-consuming.
And there it comes. git bisect
searches the broken commit by repeatedly dividing the chosen part of the git history into two sets of commits and picking the one in the middle. Each round git
indicates a commit, the user has to check.
Fundamentals
Let’s see the fundamental principle of bisect
using the example.
The following picture represents the collection of commits in some git repository. The commit that introduces the bug is filled with red color, and all its successors (yellow ones) are broken.
git bisect
helps us find the broken commit by halving the history and pointing the commit for the test. In this case, the procedure will take 3 rounds of testing as shown in the image below.
Usage
There are just 4 essential subcommands used to run the bisect: start
, good
, bad
, reset
.
To start bisecting, issue git bisect start
in the command line:
$ git bisect start
Then indicate the range of commits to check by choosing commits known to be broken (bad), and working (good):
$ git bisect good HEAD
$ git bisect bad <Broken SHA>
Now is your turn to run whatever you need to assess the correctness of a commit. At this point, git checks out to the commit that needs to be tested. Once you test it, tell git if it’s good, or bad:
$ git bisect good # if the test passed
$ git bisect bad # if the test failed
Expect a confirmation log that includes the estimated number of remaining steps:
Bisecting: 4 revisions left to test after this (roughly 2 steps)
Once git figures out the first broken commit, you will get this kind of message:
<SHA> is the first bad commit
At this point the bisect ends and the repository is checked out at the first broken commit pointed out as a result of the last step. Reset the bisect to return to the HEAD revision:
$ git bisect reset
Note: Bisect can be aborted anytime using the reset
command.
Conclusion
The git bisect is a powerful yet simple-to-use command that can help save some time during debugging. It’s especially helpful when the testing procedure is quick and repeatable. It saved me multiple times while I was working on projects developed by dozens of people and consisting of multiple repositories.
Software engineer specializing in embedded development.
An enthusiastic overthinker.