Git Bisect
What is git bisect?
Something worked before, and now it is broken, but there are many commits in between. Which one broke it?
git bisect finds that commit for you with a binary search: it checks out a commit in the middle, you say whether it is good or bad, and Git cuts the list in half. Even with 1000 commits, you only need to test about 10.
The examples below use a project with 8 commits. Somewhere along the way, the price in price.txt changed from 10 to 0 by mistake:
Example: The History
git log --oneline
7d7762f (HEAD -> main) Version 8
8e72b26 Version 7
a9b35a0 Version 6
164895e Version 5
afc612d Version 4
2931d52 Version 3
e9fcbd8 Version 2
43892cf Version 1
Try it Yourself »
Start Bisecting
Start with git bisect start, mark the current commit as bad, and a commit you know worked as good:
Example: Mark Good and Bad
git bisect start
status: waiting for both good and bad commits
git bisect bad
status: waiting for good commit(s), bad commit known
git bisect good HEAD~7
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[afc612d005bf0d7102cc08c7a879561a7eb99d78] Version 4
Try it Yourself »
Git has checked out "Version 4", in the middle. Now test it. Run your program, or in this example, look at the file:
Test and Answer
After each test, tell Git if this commit is good or bad. Git then jumps to the middle of the part that is left:
Example: Answer Until Git Finds It
cat price.txt
price = 10
git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
[a9b35a09c7d4d1f01e9b387c46cafeb36c22c4a5] Version 6
cat price.txt
price = 0
git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[164895ebef75015bb69684046f64315692b9b2e3] Version 5
cat price.txt
price = 10
git bisect good
a9b35a09c7d4d1f01e9b387c46cafeb36c22c4a5 is the first bad commit
commit a9b35a09c7d4d1f01e9b387c46cafeb36c22c4a5
Author: W3Schools <test@w3schools.com>
Date: Wed Jan 15 10:00:00 2025 +0000
Version 6
price.txt | 2 +-
version.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
Try it Yourself »
"Version 6" is the commit that broke the price. Look at it with git show to see what changed.
Finish (git bisect reset)
When you are done, go back to where you started:
Example: End the Search
git bisect reset
Previous HEAD position was 164895e Version 5
Switched to branch 'main'
Try it Yourself »
Let Git Do the Testing (git bisect run)
If you can test with a command or script, git bisect run does all the steps for you. The command must exit with 0 for good, and 1 for bad:
Example: Automatic Bisect
git bisect start HEAD HEAD~7
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[afc612d005bf0d7102cc08c7a879561a7eb99d78] Version 4
git bisect run grep -q "price = 10" price.txt
running 'grep' '-q' 'price = 10' 'price.txt'
Bisecting: 1 revision left to test after this (roughly 1 step)
[a9b35a09c7d4d1f01e9b387c46cafeb36c22c4a5] Version 6
running 'grep' '-q' 'price = 10' 'price.txt'
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[164895ebef75015bb69684046f64315692b9b2e3] Version 5
running 'grep' '-q' 'price = 10' 'price.txt'
a9b35a09c7d4d1f01e9b387c46cafeb36c22c4a5 is the first bad commit
commit a9b35a09c7d4d1f01e9b387c46cafeb36c22c4a5
Author: W3Schools <test@w3schools.com>
Date: Wed Jan 15 10:00:00 2025 +0000
Version 6
price.txt | 2 +-
version.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
bisect found first bad commit
Try it Yourself »
Git runs the command on each commit it checks out, and stops at the first bad commit.
Commands Overview
git bisect start: Start a searchgit bisect bad [commit]: Mark a commit as bad (the current one if no commit is given)git bisect good [commit]: Mark a commit as goodgit bisect skip: Skip a commit you cannot testgit bisect run <command>: Test automaticallygit bisect reset: End the search and go back