Learning Objectives
By the end of this lesson you will be able to:
- Run a bisect from start to finish and read every message it prints
- Mark commits
goodandbadand know what each does to the range - Interpret the final "is the first bad commit" output
- End a session cleanly with
git bisect reset
Starting
git bisect start
git bisect bad # HEAD is broken
git bisect good v4.1 # this tag was fine
Bisecting: 189 revisions left to test after this (roughly 8 steps)
[4c1f8ab2e94b7d0c1f5a2836b4c9d0e1f2a3b4c5d] refactor: extract discount calculation
Two things just happened. Git worked out the range — 380 commits, so 189 on each side of the midpoint — and it checked out the midpoint commit. Your working directory is now that commit, in detached HEAD.
Git also tells you the budget: roughly 8 steps. You can plan your afternoon.
The Loop
Build. Run your reproduction. Answer.
npm ci && npm run build # whatever your project needs
# run the reproduction steps
Bug present:
git bisect bad
Bug absent:
git bisect good
Either way, Git narrows and checks out the next commit:
Bisecting: 94 revisions left to test after this (roughly 7 steps)
[9d3e072a1b8c4f5e6d7a8b9c0d1e2f3a4b5c6d7e] feat: add discount audit trail
Repeat. Eight or nine iterations, and each one is exactly this: build, test, one word.
Do not switch branches during a session. Git is driving your working directory now, and moving it yourself confuses the search.
The Result
4c1f8ab2e94b7d0c1f5a2836b4c9d0e1f2a3b4c5d is the first bad commit
commit 4c1f8ab2e94b7d0c1f5a2836b4c9d0e1f2a3b4c5d
Author: Maria Kovalenko <maria@example.com>
Date: Tue Mar 12 14:22:07 2026 +0200
refactor: extract discount calculation into a helper
src/payments/discount.ts | 24 ++++++++++++++----------
src/payments/refund.ts | 8 ++++----
2 files changed, 18 insertions(+), 14 deletions(-)
Read "first bad commit" precisely. It means: this commit is bad, and its parent is good. That is the exact boundary where the behaviour changed, which is what you asked for.
Everything you need for the report is in that block — commit, author, date, message, and the files touched.
Ending the Session
git bisect reset
Previous HEAD position was 4c1f8ab refactor: extract discount calculation
Switched to branch 'main'
Do not skip this. Bisect leaves you in detached HEAD on a historical commit. Without the reset, your next commit goes nowhere attached to a branch, and your working copy looks mysteriously like last March.
reset also clears the bisect state, so the next session starts clean.
Reviewing What Happened
Before you reset, or afterwards from the log:
git bisect log
git bisect start
# bad: [7b2e551...] fix: correct totals rounding
git bisect bad 7b2e551...
# good: [e2b90d1...] release: v4.1
git bisect good e2b90d1...
# good: [4c1f8ab...] refactor: extract discount calculation
git bisect good 4c1f8ab...
This is your audit trail. Two uses for it.
Reviewing your own answers. If the result is surprising, read back through and check whether one of your verdicts was wrong.
Replaying. Save the log and someone else can reproduce your search exactly:
git bisect log > bisect-PAY-4417.txt
git bisect reset
# later, or on a colleague's machine:
git bisect replay bisect-PAY-4417.txt
Attach that file to the ticket. It makes your result verifiable rather than merely asserted.
When You Answer Wrong
If you realise mid-session that a verdict was mistaken, do not start over:
git bisect log > /tmp/bisect.txt
# edit the file, remove or fix the wrong line
git bisect reset
git bisect replay /tmp/bisect.txt
The replay redoes the whole search with the corrected answers, skipping every step you already got right.
Pro Tip: Keep a note of the commit ID and your verdict at each step, in a scratch file.
git bisect loggives you the same information, but writing it down yourself makes you slow down enough to be sure of each answer — and being sure is the entire reliability of the method.
Key Takeaways
git bisect start, thengit bisect badandgit bisect good <ref>to set the range- Git checks out the midpoint each time and tells you how many steps remain
- The loop is: build, test,
goodorbad— nothing else - Do not switch branches while a bisect is running
- "First bad commit" means this one is bad and its parent is good
git bisect resetat the end, always — it returns you to your branchgit bisect logandgit bisect replaymake a session auditable and repeatable