Engineering Craft › Version Control (Git)
Bisect
Binary-searching history to find the commit that introduced a bug.
Also known as: git bisect, bisecting, bisect a bug, finding the commit that broke it
git bisect finds which commit introduced a bug, using binary search through your history. When you know “it worked last month, and it’s broken now” but there are 300 commits in
between, it narrows them down in a handful of steps, because each test halves the range.
git bisect start
git bisect bad # the current commit is broken
git bisect good v2.3.0 # this older commit was fine (a tag, hash or branch)
Git checks out a commit in the middle. You test it and tell Git:
git bisect good # or: git bisect bad
and it picks the next midpoint. After about log₂(N) steps (300 commits take roughly 9), it announces:
3f9c2a1 is the first bad commit
Then finish and return to where you started:
git bisect reset
Automate it
If you can write a command that exits 0 when things are good and non-zero when bad (a test, or a script), Git can run the whole search itself:
git bisect start HEAD v2.3.0
git bisect run npm test -- --grep "checkout total"
Tips
- You need a reliable test. If the bug is intermittent or the check is flaky, the bisect points to the wrong commit. First reproduce it consistently.
- Choose the good commit carefully, and confirm it really is good.
- Skip commits that don’t build:
git bisect skip. - Small, atomic commits make it work best. A giant commit that mixes ten changes only tells you “somewhere in here”.
- Once found, read the commit and its message (git log), then understand why before fixing (understand before you change).
- It’s the same idea as binary search debugging applied to time.
After the fix, add a regression test.