Hands-free bisection
Manual bisect requires a human verdict at each step. git bisect run automates the loop: provide a script that exits 0 for good, non-zero for bad, and 125 for "skip this commit." Bisect will drive the search to completion, often unattended.
The contract
Your script must:
- Exit 0 when the commit is good.
- Exit between 1 and 124, or 126/127, when bad.
- Exit 125 when the commit cannot be tested (broken build, missing dependency).
- Avoid exit codes outside these ranges; 128+ aborts bisect.
Example
#!/usr/bin/env bash
set -e
make clean
make || exit 125 # untestable
./tests/regression-1234 || exit 1
exit 0
Drive bisect with it:
git bisect start HEAD v2.4.0
git bisect run ./bisect-test.sh
Inline one-liners
For quick searches you can avoid a script file:
git bisect run sh -c "make && ./run-test || exit 1"
Performance regressions
Bisect a slowdown by comparing a benchmark against a threshold:
git bisect run sh -c '
cargo build --release || exit 125
t=$(./bench --json | jq .ms)
awk -v t="$t" "BEGIN { exit (t > 250) }"'
The awk trick converts the comparison into the script's exit code.
Flaky tests
If a test is intermittently failing, run it multiple times and consider it good only if all runs pass:
git bisect run sh -c '
for i in 1 2 3 4 5; do
./flaky-test || exit 1
done
exit 0'
Common mistakes
Returning exit code 128 or higher mid-search aborts bisect — wrap commands in || exit 1 to clamp. Forgetting to git bisect reset at the end leaves you on a detached HEAD. Failing to use exit 125 for unbuildable commits causes false bads. Side-effect-laden tests that mutate the working tree confuse subsequent steps; always clean up first.
Reproducible reports
Capture the exact bisect path for postmortems:
git bisect log > bisect.log
Attach this log to the bug ticket; it doubles as a reproduction recipe. See "Automatic bug bisection with git bisect" for the manual fundamentals.