CPCODELAB
Git & GitHub

Binary Bug Hunting with git bisect

10 min read

Bisect: O(log n) Debugging

When a regression appears in a codebase with hundreds of commits between "worked" and "broken", testing each commit manually is impractical. git bisect halves the search space with every step, identifying the culprit commit in at most log₂(n) steps.

bash
git bisect start
git bisect bad                    # HEAD is broken
git bisect good v2.3.0            # v2.3.0 was the last known-good tag
# Git checks out the midpoint commit automatically
# Test it, then mark it:
git bisect good                   # midpoint is fine — bug is in the later half
# or:
git bisect bad                    # midpoint is broken — bug is in the earlier half
# Continue until Git prints: "abc1234 is the first bad commit"
git bisect reset                  # return HEAD to where you started

Automating Bisect with a Test Script

If you have an automated test that reliably reproduces the bug, let Git run it for you. The script must exit 0 for good, non-zero for bad.

bash
git bisect start
git bisect bad HEAD
git bisect good v2.3.0
git bisect run npm test -- --grep "checkout total"  # auto-bisect until done

Skipping Commits

bash
git bisect skip    # if the checked-out commit cannot be tested (e.g. build fails)

For a project with 1 000 commits between good and bad, bisect finds the culprit in at most 10 steps. For 1 000 000 commits, it takes at most 20 steps. This is why small, focused commits pay off: bisect gives you an exact answer, not a blob of 50 unrelated changes.

Ready to test yourself?
Practice Git & GitHub— quiz & coding exercises