git bisect run drives the whole binary search automatically using a test script.
Once a test cleanly distinguishes good from bad, bisect run finds the first bad commit with zero manual marking - ideal for catching regressions in CI without a human in the loop.
What it does
git bisect run executes a command at each bisection step and uses its exit code to mark the commit good, bad, or skip, halving the range automatically until it isolates the first bad commit.
Common usage
Terminal
git bisect start HEAD v1.0.0 # bad=HEAD, good=v1.0.0
git bisect run ./test.sh
git bisect run make check
git bisect reset # always clean up afterward
Options
Exit code
Meaning to bisect
0
Commit is good
1–124, 126, 127
Commit is bad
125
Skip: commit cannot be tested
≥128
Abort the bisect session
Common errors in CI
A script that returns 125 unintentionally (e.g. "command not found" is 127, but a wrapper may emit 125) corrupts the search by skipping testable commits. Make the script return 0/1 deliberately and reserve 125 for genuinely untestable builds. Always end with git bisect reset, and ensure full history (no shallow clone).
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
.github/workflows/ci.yml
- uses:actions/checkout@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
Frequently asked questions
git bisect run: Usage, Options & Common CI Errors?
Once a test cleanly distinguishes good from bad, bisect run finds the first bad commit with zero manual marking - ideal for catching regressions in CI without a human in the loop.
What it does?
git bisect run executes a command at each bisection step and uses its exit code to mark the commit good, bad, or skip, halving the range automatically until it isolates the first bad commit.
Common errors in CI?
A script that returns 125 unintentionally (e.g. "command not found" is 127, but a wrapper may emit 125) corrupts the search by skipping testable commits. Make the script return 0/1 deliberately and reserve 125 for genuinely untestable builds. Always end with git bisect reset, and ensure full history (no shallow clone).