Hunting Bugs with git bisect
Binary-search your history to pinpoint the exact commit that introduced a bug in a handful of steps.
When a bug "used to work" but you have no idea which of the last 200 commits broke it, git bisect finds the culprit with a binary search — roughly log2(N) checks instead of scanning every commit.
The manual flow
git bisect start— begin a session.git bisect bad— mark the current (broken) commit.git bisect good <sha>— mark a commit you know worked.- Git checks out a commit halfway between. Test it, then run
git bisect goodorgit bisect bad. - Repeat until Git prints "<sha> is the first bad commit".
git bisect reset— return to where you started.
Let it drive itself
If you can express the test as a script that exits 0 for good and non-zero for bad, git bisect run automates every step — walk away and come back to the guilty commit.
Example
# Manual: 20 commits collapse to ~5 tests
git bisect start
git bisect bad # current commit is broken
git bisect good v1.4.0 # this release was fine
# test the commit Git checks out, then mark good/bad, repeat...
git bisect reset # done — back to normal
# Automated: let a test script do the marking
git bisect start HEAD v1.4.0
git bisect run npm test -- --run failing.spec.js
# ... 6f3a1c9 is the first bad commitWhen to use it
- A developer uses git bisect to find the exact commit that introduced a memory leak among 500 commits in under ten minutes.
- A QA engineer combines git bisect with an automated test script to let Git binary-search the failing commit without manual testing each step.
- A team bisects a performance regression to pinpoint which dependency upgrade caused a 3x slowdown in the build time.
More examples
Start a manual bisect session
Starts a binary search between a known-bad HEAD and a known-good tag; Git checks out the midpoint commit each step for you to test.
git bisect start
git bisect bad # current HEAD is broken
git bisect good v1.2.0 # this tag was known good
# Bisecting: 250 revisions left (roughly 8 steps)
# [e4a1f3c] feat: add search indexing
# Test, then mark the checked-out commit
git bisect good # or: git bisect badAutomate bisect with a test script
bisect run executes the script at each midpoint, treating exit-0 as good and non-zero as bad, finding the culprit commit with zero manual effort.
# Exit 0 = good, non-zero = bad
cat test_for_bug.sh
#!/bin/sh
npm test -- --testNamePattern='checkout total'
# Hand the script to bisect
git bisect start HEAD v1.2.0
git bisect run sh test_for_bug.sh
# ... bisect runs automatically to the culprit commitEnd a bisect session cleanly
git bisect reset ends the session and returns to the branch you were on before bisect started, leaving no residual state.
# bisect found the culprit:
# a1b2c3d is the first bad commit
# Author: Dev Name <[email protected]>
# Date: 2026-06-12
# Return to original HEAD
git bisect reset
# Previous HEAD position was a1b2c3d
# Switched to branch 'main'
Discussion