Resourcesโ€บGit Tricksโ€บGit Bisect: Find the Commit That Broke Everything in Seconds
๐Ÿ”€Git Tricksโ€” Git Bisect: Find the Commit That Broke Everything in Secondsโฑ 5 min

Git Bisect: Find the Commit That Broke Everything in Seconds

Git bisect uses binary search to find the exact commit that introduced a bug. Here's how to use it and automate it.

๐Ÿ“…January 29, 2026โœTechTwitter.iogitbisectdebuggingworkflow

The Problem

Something is broken. You know it worked three weeks ago. You have 200 commits between "worked" and "broken." Which one introduced the bug?

Manual inspection: hours. Git bisect: minutes.


How Bisect Works

Git bisect performs a binary search through your commit history. You tell it a "good" commit (bug doesn't exist) and a "bad" commit (bug exists). It checks out the midpoint and asks you to test. You say good or bad. It keeps halving the range until it finds the exact culprit.

200 commits = 8 steps to find the bad commit (logโ‚‚ 200 โ‰ˆ 8).


Basic Usage

# Start bisect
git bisect start

# Mark current commit as bad (bug is present)
git bisect bad

# Mark a known good commit (find the last known working hash or tag)
git bisect good v2.4.0
# or by commit hash:
git bisect good a3f7b2c

# Git checks out the midpoint commit
# Test your application, then:
git bisect good  # if the bug is NOT present
git bisect bad   # if the bug IS present

# Git keeps narrowing until:
# a8f92b1 is the first bad commit
# commit a8f92b1
# Author: Alice <alice@example.com>
# Date:   Mon Jan 15 14:22:07 2026
# ...

# When done:
git bisect reset  # returns to original HEAD

Automated Bisect

The real power: run a script that tests for the bug automatically. Git bisect calls the script for each commit โ€” returns 0 (good) or non-zero (bad).

# Create a test script
cat > /tmp/test-bug.sh << 'EOF'
#!/bin/bash
npm run build 2>/dev/null || exit 125  # skip if build fails
npm test -- --grep "user auth returns 200" 2>/dev/null
exit $?
EOF

chmod +x /tmp/test-bug.sh

# Run automated bisect
git bisect start
git bisect bad HEAD
git bisect good v2.4.0
git bisect run /tmp/test-bug.sh

Git will run your script on each commit automatically and report the exact bad commit โ€” while you do something else.

Exit Codes

  • 0 โ€” this commit is good
  • 1 (non-zero) โ€” this commit is bad
  • 125 โ€” skip this commit (build broken, test doesn't apply, etc.)

Skipping Commits

Some commits in the middle won't build cleanly. Skip them:

git bisect skip  # skip current commit
git bisect skip v2.6.0..v2.7.0  # skip a range

Git works around skipped commits. It might not find the exact commit, but will narrow it to a small range.


Practical Tips

Use tags as reference points

git bisect good v2.4.0  # much easier than remembering hashes

Tag your releases. You'll thank yourself during bisect.

Write a minimal reproduction first

The better your test script, the better bisect works. A flaky test (passes sometimes, fails sometimes) makes bisect unreliable. Make your reproduction deterministic before running bisect.

Check what bisect found

git bisect log  # shows the full bisect session
git show a8f92b1  # see exactly what changed in the culprit commit

Example: Finding a Performance Regression

#!/bin/bash
# test-perf.sh โ€” exit bad if response time > 200ms

RESPONSE_TIME=$(curl -o /dev/null -s -w "%{time_total}" http://localhost:3000/api/health)
THRESHOLD=0.200

if (( $(echo "$RESPONSE_TIME > $THRESHOLD" | bc -l) )); then
  exit 1  # bad โ€” too slow
else
  exit 0  # good โ€” fast enough
fi
git bisect start
git bisect bad HEAD
git bisect good v3.0.0
git bisect run ./test-perf.sh

Key Takeaways

  • git bisect uses binary search โ€” 200 commits takes ~8 steps
  • Start: git bisect bad HEAD + git bisect good <last-known-good>
  • Automate with git bisect run <script> โ€” the script exits 0 (good) or 1 (bad)
  • Use exit code 125 to skip commits where the test can't run
  • Always end with git bisect reset to restore your working state