AlgoInsight

Q&A

What is Git Bisect?

By AlgoInsight Team2026-06-07algorithmsgit

Overview

When a bug appears but you don't know which of hundreds of commits caused it, testing each one is O(n). git bisect applies binary search: since "good" and "bad" partition history at some boundary commit, you can halve the search space with each test. Finding the culprit among 1,000 commits takes ~10 tests instead of 1,000.

graph TD
    A[Known good commit] -.many commits.-> B[Known bad commit]
    B --> C[git bisect checks out the midpoint]
    C --> D{Test: good or bad?}
    D -->|good| E[Bug is in the newer half]
    D -->|bad| F[Bug is in the older half]
    E & F --> G[Repeat on the remaining half]
    G --> H[First bad commit identified]
    style C fill:#1e1b4b,color:#fff

The Manual Workflow

git bisect start
git bisect bad                 # current commit is broken
git bisect good v1.2.0         # this older commit/tag worked
# Git checks out a commit halfway between them; you test it, then:
git bisect good                # if this commit works
# or
git bisect bad                 # if this commit is broken
# ... repeat: Git keeps halving the range ...
# eventually:
# "abc1234 is the first bad commit"
git bisect reset               # return to your original HEAD

Each good/bad you report halves the remaining commits. After ~log₂(n) iterations, Git names the first bad commit.

Automated Bisect with a Test Script

If you can write a script that exits 0 when good and non-zero when bad, Git runs the entire bisect automatically:

git bisect start HEAD v1.2.0   # bad=HEAD, good=v1.2.0 in one line
git bisect run ./test.sh       # Git runs test.sh on each midpoint
git bisect reset

Example test.sh:

#!/bin/bash
make build || exit 125     # 125 = "skip this commit" (can't be tested)
./run_tests --case bug42   # exit 0 = good, non-zero = bad

exit 125 tells bisect to skip a commit that can't be tested (e.g. won't compile).

Skipping Untestable Commits

git bisect skip            # current commit can't be tested; try a nearby one

How the Binary Search Works

Git assumes the property is monotonic: once the bug is introduced it stays "bad." So history splits into a good prefix and a bad suffix, and the boundary is the first bad commit. Binary search finds that boundary: test the middle; if good, the boundary is in the newer half; if bad, it's in the older half; recurse. That's why it's O(log n).

Practical Tips

Why This Matters in Interviews

Git/debugging questions use bisect to test whether you know efficient debugging beyond git log reading. The key points: it's binary search over commit history (O(log n) vs O(n)), the good/bad marking workflow, automation via git bisect run with exit codes, and the monotonicity assumption (bug stays present once introduced). Mentioning exit 125 to skip untestable commits is a strong detail.

Common Pitfalls

References

More answers