🔪 Bisecting commits like a PRO

Or how to utilize automation when finding the source of a bug.

Martin Džejky Jakubik
2 min readMar 22, 2020

Here’s a new thing I learned this week.

You know how you can instruct git to run a bisect using git bisect start. This process is used to find a commit which introduced a change into your code. The change could either be a bug or some feature that has been implemented. That’s why you can mark commits good/bad or old/new (or use entirely custom words). You can read more about bisecting in the official documentation.

The usual process of finding the first commit that introduced a change looks something like this:

  1. Start the bisecting process using git bisect start.
  2. Mark 2 distinct commits, 1 as good and 1 as bad. Usually the HEAD is bad if you are trying to find the source of a bug; and some old commit without the bug is marked good. For example, git bisect bad HEAD && git bisect good ef8849b
  3. Git checks out a commit. You run your tests or otherwise determine whether this commit is good or bad and tell it to git using git bisect good/bad.
  4. Git then checks out another commit and you repeat the process.
  5. This procedure is repeated until git finds the right commit that is the first bad commit in your repository.

Now, notice that there is a series of manual steps required for each commit. Depending on the number of commits to bisect, you have to run the manual steps several times, perhaps even tens of times in total.

There’s a better, automatic way to do this. You just have to write a script that exits with exit code 0 if the commit is good and some other exit code when the commit is bad (more about which specific exit codes are supported can be found in the documentation). A simple script which does this could look like this (for a project using npm):

#!/usr/bin/env bash# fail if any of the commands fail
set -o errexit
# clean and install node modules
rm -rf node_modules/
npm ci
# run tests
npm run test

Then you start the git bisect process, mark your good and bad commits, and let the automation do its job:

git bisect run ../your-script.sh

2 things to note here:

  • Place the script outside of your repository because git needs a clean state to run the bisect.
  • I wasn’t able to simply use git bisect run "npm ci && npm run test". You have to create a script file and use that to run the bisect.

Thanks for reading this short article. As you may have noticed, I have been inactive on Medium for a loooong time. I simply though that I don’t have anything to write about. And, let’s be honest, I got lazy. In reality, I just had high expectations about topics I could possibly make an article about.

Anyway, given the current situation, I have more time to spend in front of a computer. I’ll make sure to put that time to good use. For the time being, stay safe and healthy! 😷

--

--

Martin Džejky Jakubik

Frontend developer @ Exponea. Writing about things I learn along the way.