Binary search through history
git bisect performs binary search across commits. Tell it a known-good commit and a known-bad commit; it checks out the midpoint and asks you to mark it good or bad. After log2(N) steps, it identifies the first bad commit. For 1024 commits, that is ten checks.
Manual bisect
git bisect start
git bisect bad HEAD
git bisect good v2.4.0
# Git checks out the middle commit. Test it.
git bisect good # if the bug is absent
git bisect bad # if the bug is present
# Repeat until Git prints the offending SHA
git bisect reset # return to HEAD
Automated bisect
If you can write a script that exits 0 for "good" and non-zero for "bad", bisect runs unattended:
git bisect start HEAD v2.4.0
git bisect run ./scripts/reproduce-bug.sh
The script can be a unit test, a curl-and-grep, or anything that decisively classifies a commit.
Skipping untestable commits
If a checked-out commit cannot be evaluated (broken build, missing dependency, irrelevant), skip it:
git bisect skip
Bisect will pick a nearby commit instead.
Bisect with terms beyond good/bad
Hunting for a regression where the issue is "slow" rather than "broken"? Customise the terms:
git bisect start --term-old=fast --term-new=slow
git bisect slow HEAD
git bisect fast v2.4.0
What makes bisect feasible
Bisect is most powerful when:
- Commits are atomic - each commit builds and tests pass.
- Tests are reproducible - flaky tests poison bisect.
- The bug is deterministic - intermittent bugs need scripted retry logic.
A real-world example
You discover a memory leak in production. The last release was fine; HEAD leaks. Run:
git bisect start HEAD v3.0.0
git bisect run ./test-memory.sh
An hour later, bisect prints the SHA of the commit that introduced the leak. You diff that one commit and the cause is in 30 lines instead of 30,000.
Bisecting merge commits
Pass --first-parent to bisect only along trunk:
git bisect start --first-parent HEAD v2.4.0
This avoids descending into feature branch interiors when the bug was integrated as a merge.
Visualising progress
git bisect log
git bisect visualize # opens gitk on the candidate range
Bisect turns "I have no idea what broke this" into a 20-minute, mechanical exercise. Internalise the workflow; it pays off the first time you have to find a regression in a thousand-commit window.