git bisect
I have long been aware of git bisect
but I have never used it. I assumed it was complex as I had never actually read about it properly. In the past when non-obvious regressions have crept in I have stepped through commits, tested and repeated until I found the regression. I have also jumped forward and back doing some sort of manual binary search whilst keeping track of my findings in a markdown file.
Today I had the pleasure of tracking down a regression that was potentially weeks old and I just did not have the energy for my antiquated manual fumbling. So, I read the documentation and found it was far easier than my stupid assumption!
This command uses a binary search algorithm to find which commit in your project’s history introduced a bug. You use it by first telling it a “bad” commit that is known to contain the bug, and a “good” commit that is known to be before the bug was introduced. Then git bisect picks a commit between those two endpoints and asks you whether the selected commit is “good” or “bad”. It continues narrowing down the range until it finds the exact commit that introduced the change.
git-bisect documentation
git bisect session example
Start a bisect session.
$ git bisect start
status: waiting for both good and bad commits
Mark a good commit, a commit where everything still worked. Here I am using a commit hash, you can also use a tag.
$ git bisect good e631aaf
status: waiting for bad commit, 1 good commit known
Now mark a bad commit, a commit where the bug is present (likely the current HEAD
).
$ git bisect bad be292f57
Bisecting: 15 revisions left to test after this (roughly 4 steps)
[d1e2ced8f1a0fe0cc6c354ac0e521c5152b9184e] feat: adds login flow
Note the response from git. It tells us how many commits are left to test and how many steps it will take to find the bad commit. Then we see the commit hash and message for the commit that git has checked out for us to test. This is a midpoint commit between the good and bad commits.
Bisecting: 15 revisions left to test after this (roughly 4 steps)
[d1e2ced8f1a0fe0cc6c354ac0e521c5152b9184e] feat: adds login flow
Now run your application and verify if the bug is present or not then mark it as good or bad.
If the bug still exists, mark it as bad.
$ git bisect bad
If the bug is not present, mark it as good.
$ git bisect good
Keep repeating these steps until git tells you it has found a bad commit.
08be2ad is the first bad commit
Bad commit
When git has found the bad commit it will show you the commit details.
commit 08be2ad70aaaea85e41410f5d657dc25f92cfdd9
Author: Jane Doe <[email protected]m>
Date: Wed Apr 23 14:31:52 2025 +0100
fix: filter users by role
affected/files/constants.ts | 28 +++++++++++++++
affected/files/User.tsx | 7 ++--
affected/files/Users.tsx | 27 +++++++-------
affected/files/types.ts | 17 ++-------
affected/files/utils.ts | 41 +++++++++++-----------
Once done, reset the bisect session to return to your original branch. You now have the bad commit, which is half the work, and can you can debug from there.
git bisect reset
Summary
Save yourself some pain and use git bisect
!