git bisect — Finding Bugs
git bisect performs a binary search through your commit history to find the exact commit that introduced a bug. Instead of checking every commit one by one, it cuts the search space in half each time.
Why Binary Search?
If you have 1000 commits, checking each one takes up to 1000 steps. Binary search takes at most 10 steps. That's the power of git bisect.
1000 commits → ~10 steps
100 commits → ~7 steps
50 commits → ~6 steps
How It Works
- You tell Git one "good" commit (where the bug doesn't exist) and one "bad" commit (where it does)
- Git checks out the commit halfway between them
- You test and tell Git if this commit is "good" or "bad"
- Git narrows the range and repeats
good ——— ? ——— ? ——— ? ——— ? ——— bad
↓
good ——— ? ——— [test this] ——— ? ——— bad
↓ (bad)
good ——— [test this] ——— bad
↓ (good)
good ——— [THIS COMMIT INTRODUCED THE BUG] ——— bad
Basic Commands
git bisect start # begin bisecting
git bisect bad # mark current commit as bad
git bisect good abc1234 # mark a known good commit
# Git checks out a middle commit...
git bisect good # if this commit works
git bisect bad # if this commit is broken
# Repeat until Git finds the culprit
git bisect reset # finish and return to original branch
Try it!
Practice finding a bug with bisect:
- Set up a repo with a series of commits:
git init && echo "working" > app.txt && git add app.txt && git commit -m "v1: working" - Add more "good" commits:
echo "working v2" > app.txt && git add app.txt && git commit -m "v2: still working" echo "working v3" > app.txt && git add app.txt && git commit -m "v3: still working"- Introduce the "bug":
echo "BROKEN" > app.txt && git add app.txt && git commit -m "v4: refactor" - Add commits after the bug:
echo "BROKEN v5" > app.txt && git add app.txt && git commit -m "v5: add feature" echo "BROKEN v6" > app.txt && git add app.txt && git commit -m "v6: more work"- Now find the bug! Start bisect:
git bisect start - Mark current as bad:
git bisect bad - Mark the first commit as good:
git bisect good HEAD~5 - Git checks out a middle commit. Check the file:
cat app.txt - If it says "working", run
git bisect good. If it says "BROKEN", rungit bisect bad - Repeat step 10-11 until Git identifies the first bad commit
- Clean up:
git bisect reset
Automated Bisect
You can automate bisect with a test script:
git bisect start HEAD HEAD~20
git bisect run ./test.sh
The script should exit with code 0 for "good" and non-zero for "bad". Git will find the culprit automatically.
Tips
- Write good commit messages — they help you understand what each commit changed when bisecting
- Keep commits small — a bisect that lands on a 500-line commit is harder to debug than one with 10 lines
- Use automated tests —
git bisect runwith a test script is the fastest way to find bugs