When something that used to work is broken, git bisect finds the exact commit responsible in a handful of steps. In this lesson you will bisect manually, automate it with a test command, and learn how testers use it to pinpoint regressions.
📖 What You’ll Learn: how bisect uses binary search, a manual bisect step by step, automatic bisect with git bisect run and exit codes, a script that skips unbuildable commits, other bisect commands, and what makes bisect work well.
🔍 What Is git bisect?
A test passed last week and fails today. Fifty commits were made in between. Which one broke it? git bisect finds out with a binary search: it checks out a commit halfway between a known good and a known bad commit, you say whether it is good or bad, and Git halves the range again.
| Commits to search | Maximum steps |
|---|---|
| 16 | 4 |
| 100 | 7 |
| 1,000 | 10 |
For testers this is a superpower: you can hand developers the exact commit that introduced a regression.
🧭 Manual Bisect Step by Step
git bisect start
git bisect bad # the current commit is broken
git bisect good v2.3.0 # this tag (or commit hash) was fine
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[7c8d9e0] Add discount code field to cart
Git checks out a commit in the middle. Test it (run the app or the failing test), then tell Git the result:
npx playwright test tests/checkout.spec.ts
git bisect good # if it works on this commit
# or
git bisect bad # if it is broken on this commit
Repeat until Git reports:
3e4f5a6b is the first bad commit
commit 3e4f5a6b...
Author: Ravi Kumar <ravi@example.com>
Change tax calculation to use rounded subtotal
Finish and go back to where you started:
git bisect reset
⚠️ Common mistake: During bisect you are in detached HEAD state on old commits. Do not commit there. Always finish with git bisect reset.
🤖 Automatic Bisect with a Script
If a command can tell good from bad by its exit code, Git can do all the steps for you:
git bisect start HEAD v2.3.0 # bad first, then good
git bisect run npx playwright test tests/checkout.spec.ts
git bisect reset
| Exit code of the command | Meaning for bisect |
|---|---|
0 | Good commit |
1 to 127 (except 125) | Bad commit |
125 | Cannot test this commit: skip it |
Any test runner works: npm test, pytest tests/test_login.py, mvn test or a custom script.
Example script that skips commits which do not build
#!/bin/sh
# bisect-check.sh
npm ci || exit 125 # cannot install: skip this commit
npx playwright test tests/checkout.spec.ts # 0 = good, non-zero = bad
chmod +x bisect-check.sh
git bisect start HEAD v2.3.0
git bisect run ./bisect-check.sh
💡 Tip: Keep the bisect script outside the repository (or untracked), otherwise it disappears when Git checks out older commits.
🧰 Other Bisect Commands
| Command | Use |
|---|---|
git bisect skip | The current commit cannot be tested (for example it does not build) |
git bisect log | Show the decisions so far |
git bisect visualize (or view) | Show the remaining commits in git log or gitk |
git bisect terms --term-old fast --term-new slow | Use other words, e.g. to find a performance change |
💡 Bisect Works Best When…
- Commits are small and each one builds: large, broken intermediate commits make bisect skip a lot (commit messages and practices).
- You have a reliable automated test that reproduces the problem; flaky tests give wrong answers (flaky tests).
- You know a good tag or commit: tag releases so you can say “it worked in v2.3.0” (tags).
📝 Assignment
- In
git-practice, create 10 commits where the 7th commit changesapp.txtto contain the wordBROKEN. - Find that commit with a manual bisect, testing with
grep -q BROKEN app.txt && echo bad || echo good. - Repeat with
git bisect run sh -c "! grep -q BROKEN app.txt"and compare the result. - Use
git bisect skipon one commit and checkgit bisect log. - Bonus: use bisect on a real project to find which commit made a test fail.
❓ FAQ
🤔 What does git bisect do?
It finds the commit that introduced a bug by binary search between a known good and a known bad commit.
🤔 How do I use git bisect?
git bisect start, git bisect bad, git bisect good <commit>, then test each commit Git checks out and mark it good or bad until it reports the first bad commit; finish with git bisect reset.
🤔 How do I automate git bisect?
git bisect run <command>: the command’s exit code marks each commit (0 good, 125 skip, other non-zero bad).
🤔 How do I exit git bisect?
git bisect reset returns to the branch and commit where you started.
🤔 Can testers use git bisect?
Yes. With an automated test that reproduces a bug, bisect pinpoints the exact commit that caused a regression.
🎯 Next Steps
🎬 Learn Git and GitHub step by step: watch the series on YouTube!
Subscribe to SqaToolsByDY • Practice on sqatools.in