Like it!

Join us on Facebook!

Like it!

Find buggy commits with git bisect

A quick and managed way to understand which commit in your project’s history introduced a bug.

Imagine you've just found a weird behavior in your git-managed project, definitely a bug introduced somewhere during the development. The first reasonable thing to do is going back in the git history until you find the exact commit that caused the error, so that you can understand what went wrong exactly. You have two options:

  1. check out every commit manually, starting from the current one going backwards, until you find the culprit;
  2. ask git bisect for help.

The git bisect command is probably a better way to solve the issue. Like option 1), git bisect will search for the commit that introduced a bug. However, it will do it automatically for you without the need of calling git checkout ... multiple times, manually. On top of that, git bisect performs the so-called binary search, much faster than the linear one. Let's see how the whole thing works!

1. Find a bug-free commit

The first thing to do is to find a relatively old commit that works. Take a look at your git log command and pick a commit that is bug-free. It will take some trial and error at first. Eventually, you would end up with the following git log scenario (comments on the right have been added by me):

31dfab2c Add new HTML template              <---- this is buggy
055958a8 Include script.js
c6c3c555 Fix macOS build

[... lots of other commits here ...]

250e8add Fix master volume not parsed
8c563c01 Optimize UI rendering
a545d17b Improve event handling             <--- this is bug-free

In words, commit 31dfab2c is the most recent commit that contains the bug, while a545d17b is one of the older commits that doesn't show the buggy behavior. You still don't now exactly which commit introduced the bug, but it definitely lies between the two above.

2. Enable the git bisect mode

Enter the git bisect mode with the following command:

git bisect start

Nothing happens here, git bisect just started. Then tell git which commit is buggy and which one is bug-free with the following commands:

git bisect good [commit]
git bisect bad [commit]

In our example that would be:

git bisect good a545d17b
git bisect bad 31dfab2c

At this point git will automatically checkout to a certain commit: the git bisect operation has started.

3. Test the commit and mark it

Since you have changed the current commit, it's time to build and run your project. If the bug is still there, tell git this commit is bad with the following command:

git bisect bad

otherwise tell git this commit is bug-free with:

git bisect good

Once done, git will checkout to another commit until there are no more left to inspect. Repeat this point 3. until git will tell you to stop.

4. Buggy commit found: inspect it

Eventually git will run out of commits to checkout: it will print out a description of the first bad one, for example:

Author: author <author@yourmail.com>
Date:   Sun May 3 16:34:21 2020 +0200

    Add new Import module

:040000 040000 3bb45a00c6ad23c3a6205cfd19c6a4d6788fe219 91072ae36bf1faab4c465a2136e5c9b5c8169219 M  src

This commit is the one that introduced the regression. You can study it to find the issue.

5. Terminate the git bisect mode

Once understood what's wrong, use git bisect reset to put everything back on the original state before the git bisect operation. This will end the bisect session and bring you back to your original commit. You can also invoke this command anytime during a bisect operation in case you want to abort it.

Sources

https://git-scm.com/docs/git-bisect
https://stackoverflow.com/questions/4713088/how-to-use-git-bisect
https://en.wikipedia.org/wiki/Binary_search_algorithm

comments