Git Bisect Tutorial: Find the Bad Commit Fast
Use git bisect to binary-search through history and pinpoint the commit that introduced a regression, with manual and automated examples.
What you'll learn
- ✓How binary search applies to commits
- ✓Running git bisect manually
- ✓Automating bisect with a script
- ✓Skipping broken commits
- ✓Avoiding common bisect mistakes
Prerequisites
- •Comfortable with git log and checkout
What and Why
When a regression sneaks in, you might know it worked last month and broke today. git bisect performs a binary search across history to find the exact commit that introduced the problem. With a clean repo and a reproducible test, you can isolate a single commit out of thousands in just a few steps.
Mental Model
Tell git two commits: one good, one bad. Git checks out a commit halfway between them. You run your test and mark the result. Git narrows the range. Eventually one commit is left, and that is the culprit.
bad <----------|---------|----------|---------> good
mid1
mid2
mid3
found Hands-on Example
Manual flow.
git bisect start
git bisect bad # current HEAD is broken
git bisect good v1.4.0 # last known good tag
# git checks out a midpoint
./run_tests.sh
git bisect good # or: git bisect bad
# repeat until git prints the first bad commit
git bisect reset # return to your branch
Automated flow. Provide a script that exits 0 if the commit is good and non-zero if bad.
# check.sh
#!/usr/bin/env bash
set -e
npm install --silent
npm test --silent -- --run path/to/regression.test.ts
chmod +x check.sh
git bisect start HEAD v1.4.0
git bisect run ./check.sh
Skip commits that cannot be tested, like ones that fail to build.
git bisect skip
A real session might end like this.
72 revisions left to test after this (roughly 7 steps)
[abc123] feat: add cache layer
...
The first bad commit is:
commit a1b2c3d4
Author: Sam <sam@example.com>
Date: Wed Mar 5 11:02:33 2026
refactor: invalidate cache on user update
You now know exactly where to look. Review the diff with git show a1b2c3d4 and write a regression test before fixing.
Common Pitfalls
- Marking commits wrong. One incorrect
goodorbadwill lead bisect to the wrong place. Re-run if you suspect a mistake. - Forgetting to reset. Always
git bisect resetto leave a clean working tree. - Inconsistent reproduction. If the bug is flaky, bisect amplifies the flake. Stabilize your test first.
- Running expensive setup at every step. Cache builds or use
git bisect runwith a quick check that only runs the smallest necessary suite.
Practical Tips
- Use exit code 125 in your script to signal “untestable” so git skips that revision.
- Combine bisect with
git worktreeto keep your main checkout untouched. - Pair bisect with
git log --oneline --grep=regexto narrow the suspect range before you start. - When the bad commit is a merge, bisect into the merged branch with
git bisect --first-parentif you want to ignore feature internals. - Document the bisect result in the bug ticket. It saves the next person hours.
Wrap-up
git bisect turns “somewhere in 800 commits” into “one specific change” in a handful of steps. The key is a reliable test and honest answers about good and bad. Once you have those, bisect does the math, and your debug time drops from days to minutes. Add the bisect run automation to your toolbox and you will reach for it instinctively the next time something breaks.
Related articles
- Git Git Cherry-pick and Revert Tutorial
Learn how to copy specific commits across branches with cherry-pick and how to safely undo merged changes with revert, including conflict handling and recovery.
- Git Git Pull Request Best Practices
How to open pull requests reviewers actually enjoy: small scope, clear descriptions, good commit hygiene, useful CI, and how to handle review feedback without endless back-and-forth.
- Git Git Rebase vs Merge: When to Use Which
A clear, practical guide to choosing between git rebase and git merge, with safe workflows for feature branches, shared branches, and pull requests.
- Git Git Stash Tutorial: Saving Work in Progress
Learn how to use git stash to safely shelve uncommitted changes, switch contexts, and recover work using push, pop, apply, and branch workflows.