The simplest possible intro to git bisect

tom.hicks
Published on April 8th 2020
git bisect

Overview

Git bisect is a built-in part of git that is easy to use, incredibly useful when the need arises, but also relatively unknown and underappreciated.
In short
git bisect will find the commit that introduced a change
So if you're ever in the situation where something has broken, or some other change was introduced, and you want to know where in the history it happened, git bisect is the tool to use.

How it works

You need to tell git some range of commits to look through, where at the start of this range the code is "good", and at the end is "bad". Bisect will then go through the commits and you must tell it at each stage whether the code is now "good" or "bad", until it finds the commit that first made it "bad".
It uses a binary search to efficiently step through the changes. You can go through hundreds of commits in just a handful of steps. This makes git bisect incredibly powerful and efficient.
If you have a shell command that will exit 0 for good and exit > 0 for bad (like a unit test), the entire process can be automated!

Example

Here's a visual walkthrough of it.
Firstly, your commits look like this, you just don't know it yet:
A git commit log
Somewhere in there, the code went from good (bottom, green) to bad (red, top).
You start by telling it a known bad point – in this case the HEAD commit.
A git commit log
Next, you find some old commit where you know the code is good (in this example we check this by running a unit test) and tell bisect that this commit is good.
The git commit log
Git will immediately jump to the commit in the middle of these known good and bad commits. You find out whether this commit is good or bad, and inform git. In this case it is bad.
The git commit log
Because this commit is bad, all the subsequent commits must also be bad, so git gets to work on the remaining grey commits.
It jumps to the next "middle" commit (there is no exact middle so it will pick one of the two middle commits), and again you tell git whether this commit is good or bad.
The git commit log
In this case it is good, which means it can colour the rest of the graph in, and determine exactly which commit introduced the breaking change.
The git commit log

Automating it further

If you have an test you can run from the CLI that has a non-zero exit code in the case of a failure (like unit tests), you can automate the entire process.
Remember when we were in this position, where we had identified our one known good and one known bad commit?
The git commit log
If you now run this command
1git bisect run [your test command here]
The git commit log
It will perform the same binary search as before, but at each step, it runs the test command, automatically marking each commit as good and bad until it finds the first bad commit!
The git commit log highlighting the first bad commit

Try it yourself

I have prepared a repo where you can try this out to find which commit introduced a bug. The bug can be detected using this command:
1npm test
which means you can try the fully automated version!
You can check out the repo here: https://bitbucket.org/tom-hicks/bisectathon

Be the first to download the app

Help us build a place where community meets knowledge. Try it out and let us know what you think.
Download on the App StoreGet it on Google Play