Technology

Finding bugs with git bisect

Adam Halesworth
Adam Halesworth
14 Jan 2022
blog post featured image

Has a tester ever pushed your feature back because you've caused a regression, but you're not 100% sure where the bug was introduced? You'd have to check out each individual commit of a list of potentially hundreds to find the issue, or...

Git bisect is a command that performs a search on your commit history, allowing you to pinpoint the exact commit a bug was introduced.

What makes it so powerful is that this search is a binary one, meaning git repeatedly divides in half a set of commits where the bug is known to exist. It continues dividing until you're left with a single commit, the one containing the bug. This makes the process exceptionally efficient. For example, if you know a bug is somewhere in 128 commits since main, it will only take 7 guesses to figure out which one.

Start the bisect!

To instruct git that you'd like to start bisecting the current repository, use:

$ git bisect start

Check out a commit that you know contains the bug (say the tip of develop) and instruct git that this commit is a bad one:

$ git bisect bad

Now that we have our bad starting point, tell git which commit is a known good one (say the tip of main):

$ git bisect good main

These good and bad starting points provide git with a range of commits to search through.

Good, bad, bad, good, good, bad

The next steps are repetitive, but for good reason. After starting the bisect, git will check out a commit for you to test. The idea here is to perform whatever step is required to determine if the bug is present. This might be compiling the source code, running automated tests, manually testing an app and so on.

If the bug is present, let git know by running:

$ git bisect bad

Git will now search for and checkout another commit to test. If the bug isn't present, let git know:

$ git bisect good

You continue marking each commit as good/bad and at each step you will see output (similar to the following) which lets you know how many steps are left:

$ Bisecting: 31 revisions left to test after this (roughly 5 steps)

When there are no more steps left to perform, git will output details of the offending commit. At this point you are free to examine the changes in more detail.

Finishing up

Once you've handled the bug like a rockstar, use

git bisect reset 

to finish bisecting and git will return you to your original HEAD commit.

I'll be honest, I'm shocked that I've not used this previously, but it's definitely now a tool in my toolbox that I'll be using regularly.

Fancy joining our talented team of developers? Check out our current vacancies.

Close chatbot
Open chatbot
Open chatbot