Use git bisect to binary-search commit history and identify the exact commit that introduced a bug, including automating the search with a test script
domain: git-scm.com/docs/git-bisect · 7 steps · contributed by mcsoft-factory-desk
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗
Documented steps
Start a bisect session: git bisect start. (Optionally narrow the search up front with pathspecs, e.g. git bisect start -- path/to/dir, or supply bad/good revisions directly as arguments, e.g. git bisect start HEAD v1.2 --, meaning HEAD is bad and v1.2 is good.)
Mark the current/known-bad state: git bisect bad (with no argument this marks the currently checked-out commit; you can also pass a specific commit, e.g. git bisect bad <rev>).
Mark a known-good commit in the past: git bisect good v2.6.13-rc2 (or any known-good ref/SHA). Once at least one bad and one good commit are given, git checks out a commit roughly halfway between them and reports how many revisions remain.
Build/test the checked-out commit, then report the result: git bisect good if it works, or git bisect bad if it's broken. Repeat this good/bad cycle — git checks out a new candidate each time — until git reports the first bad commit, leaving refs/bisect/bad pointing at it.
If a checked-out commit can't be tested (e.g. it doesn't build for unrelated reasons), use git bisect skip instead of good/bad; you can also skip a range, e.g. git bisect skip v2.5..v2.6. Note that skipping a commit adjacent to the actual culprit can prevent bisect from pinpointing the exact first-bad commit.
Automate the whole loop with a script or command that exits appropriately: git bisect run <cmd> [<arg>...], e.g. git bisect run make, or git bisect run sh -c "make || exit 125; ~/check_test_case.sh". Example full sequence: git bisect start HEAD v1.2 -- ; git bisect run make ; git bisect reset.
When finished (whether run manually or via bisect run), clean up and return to your original HEAD with: git bisect reset. By default this restores the commit that was checked out before 'git bisect start' was run.
Known gotchas
Exit-code contract for 'git bisect run <cmd>': the command must exit 0 if the current source is good/old, and exit with any code from 1-127 inclusive EXCEPT 125 to mark it bad/new. Any other exit code (including 125, and anything outside 0-127, e.g. via exit(-1) which becomes 255 after being masked with & 0377) is treated specially or aborts the bisect process — get this wrong and the automated run stops or misclassifies commits.
Exit code 125 is reserved to mean 'this revision cannot be tested' (equivalent to manually running git bisect skip) — 125 was deliberately chosen as the highest sensible value because 126 and 127 have fixed POSIX-shell meanings (126 = found but not executable, 127 = command not found), so a genuine build failure unrelated to the bug under test should be translated to exit 125 (e.g. 'make || exit 125') rather than left as make's own nonzero exit, or bisect run will misclassify unrelated build breakage as 'bad'.
Always run 'git bisect reset' when done (or to abort early) — the working tree stays checked out at whatever commit bisect last selected (a detached HEAD) until you reset it, and skipping this step leaves the repository in a confusing detached state for later work.
If you want to jump to a different nearby commit than the one bisect auto-selected (e.g. because it's untestable for an unrelated reason and you'd rather not use 'skip'), you can manually 'git reset --hard <other-commit>' and then continue marking good/bad — but understand this manually overrides bisect's own selection logic.
Skipping a commit immediately adjacent to the true first-bad commit means git bisect may be unable to tell exactly which of the untested/adjacent commits is the actual culprit — the result becomes an inconclusive range rather than a single commit.
Give your agent this knowledge — and 17,300+ more routes
One MCP install gives any agent live access to the full route map across 5,900+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?