Locating the commit that introduced a regression, or some undesirable change, in a codebase can be difficult. Locating the same in a frequently-changing codebase with a large number of contributors is harder again.
Fortunately git bisect
provides a helpful tool for doing precisely this. Rather than performing a linear search of the commits, git bisect
uses a clever binary search algorithm to locate the offending commit far more efficiently.
Having identified a commit from the past where the regression did not exist (e.g. git checkout
a commit from say a month ago), my typical usage of git bisect
is along the lines of:
- Check out the branch containing the regression and run
git bisect start
. - Label the good and bad commits:
git bisect good <commit hash>
andgit bisect bad <commit hash>
. The current commit is taken if the commit hash argument is omitted. - Bisecting commences — a candidate commit is automatically checked out and the number of revisions left to test and number of remaining steps are printed. You can run
git bisect reset
to abort at any stage. - Check whether the regression still exists, whether this involves running an automated test or taking manual replication steps. If the candidate commit contains the regression, run
git bisect bad
, otherwise rungit bisect good
. If any search area remains, another candidate commit is automatically checked out. - Repeat #4 until the bisecting process concludes and the bad commit's hash is listed.
Given git bisect
's binary search technique, the number of steps required will only increase logarithmically as the number of commits increases — this is a time-saving tool that I turn to again and again.