You know the drill. Something broke, it worked last Friday, and now you are flipping through git log trying to guess which change is guilty. Stop guessing. Git has a tool built exactly for this job: git bisect.
bisect does the search for you, and far faster. It walks your history the way a binary search walks a sorted list. Give it one commit you know is bad and one you know is good, and it picks a commit in the middle of that range, checks it out, and waits for your verdict. Your answer discards half the remaining suspects, and each round halves the field again.
The manual loop
Start a session and mark your two reference points:
git bisect start
git bisect bad # current HEAD is broken
git bisect good v1.2 # v1.2 is a known good commit
With one good and one bad commit in hand, git checks out the midpoint and prints something like:
Bisecting: 675 revisions left to test after this (roughly 10 steps)
Now the real work: build, run, and answer the question "is this working?"
git bisect good # the checked-out commit is fine
git bisect bad # the checked-out commit is broken too
Each answer narrows the range, and git picks the next midpoint:
Bisecting: 337 revisions left to test after this (roughly 9 steps)
Keep going, and eventually the loop runs out. Git prints the culprit:
<commit-hash> is the first bad commit
That hash is your answer, and refs/bisect/bad is left pointing at it.
Note the halving in the numbers above: 675 becomes 337, roughly half. That is the whole trick. A thousand commits take about ten checks, and even ten thousand only fourteen.
Automate it with git bisect run
Testing by hand is fine for a few rounds, but tedious across many. If you can shell out a check, let git drive. Define a script that reports the verdict by its exit code:
0means the commit is good.- exit codes
1–127, except125, mean it is bad. 125means skip: this commit cannot be tested (say, it does not even compile), so git sets it aside and keeps going.
Then point bisect run at your command, and git loops until it finds the first bad commit:
git bisect start HEAD v1.2
git bisect run make
Here make is the test. If the build succeeds it exits 0 (good); if it fails it exits nonzero (bad). Git runs it on every midpoint for you. This is how many projects bisect regressions unattended.
Clean up when you are done
git bisect reset
This returns you to your original HEAD and throws away the bisect refs. The command is always safe to run, even mid-session, if you want to bail out.
Pick good boundaries
bisect is only as good as the commits you give it. The bad commit must actually be broken, the good commit must actually work, and the good point should be recent enough that the real culprit sits between the two. Give it a clean, reliable test, and what used to be an afternoon of staring at diffs becomes ten quiet checks.