Skip to content

Drill: Find a Regression with git bisect

Goal

Use git bisect to perform a binary search through commit history and find the exact commit that introduced a bug.

Setup

  • A git repository with history containing a known regression
  • A way to test whether a commit is good or bad (manual check or script)

Commands

Set up a practice scenario:

mkdir /tmp/bisect-drill && cd /tmp/bisect-drill && git init
for i in $(seq 1 20); do
  echo "version $i" > app.txt
  [ $i -ge 12 ] && echo "BUG" >> app.txt  # bug introduced at commit 12
  git add app.txt && git commit -m "commit $i"
done

Start bisecting:

git bisect start

Mark the current (latest) commit as bad:

git bisect bad

Mark a known good commit:

git bisect good HEAD~19

Git checks out a middle commit. Test it and mark:

cat app.txt  # check for "BUG"
git bisect good  # or git bisect bad

Repeat until bisect identifies the first bad commit. Automate with a script:

git bisect reset
git bisect start HEAD HEAD~19
git bisect run sh -c '! grep -q BUG app.txt'

View the bisect log:

git bisect log

Reset when done:

git bisect reset

What to Look For

  • Bisect halves the search space with each step (20 commits takes ~4-5 steps)
  • The final output shows "first bad commit" with the exact commit hash and message
  • bisect run automates the process with an exit code (0 = good, 1-124 = bad, 125 = skip)
  • bisect log shows the full decision history for review

Common Mistakes

  • Forgetting to git bisect reset and leaving the repo in a detached HEAD state
  • Marking a commit incorrectly (good vs bad swapped) which gives wrong results
  • Not using git bisect skip when a commit cannot be tested (build broken, etc.)
  • Writing a test script that returns exit code 128+ (bisect treats this as an error)

Cleanup

rm -rf /tmp/bisect-drill