DEV Community

Nico Reyes
Nico Reyes

Posted on

Git bisect saved me from a week of debugging. Should've used it sooner.

Git bisect saved me from a week of debugging. Should've used it sooner.

Two weeks ago, my coworker merged a feature branch on Friday afternoon. By Monday morning, half our test suite was red. Nobody knew which commit broke things. The branch had 47 commits.

I did what most devs do. Opened git log, stared at it, closed it. Forty-seven commits. No way I was reading all of them.

So I did what any reasonable person would do. Blamed everyone in the commit history until I found someone to be mad at. Just kidding. Mostly.

The manual approach

Git blame told me which lines changed but not why they broke. Git log showed me filenames but not the actual damage. I spent two days narrowing it down manually. Checked out commit one by one. Ran tests. Watched them fail. Checked out another. Ran tests. Watched them fail.

My approach was scientific. My time investment was not.

# What I was doing (spoiler: wrong)
git checkout commit-xyz
npm test  # 47 times
Enter fullscreen mode Exit fullscreen mode

Forty-seven times. At 3 minutes per run, that's over two hours of pure waiting. Plus the checkout time. Plus the context switching.

Enter git bisect

A senior dev walked by, saw my screen, and asked why I wasn't using git bisect.

I didn't have a good answer.

Git bisect does binary search on your commit history. You tell it a known good commit and a known bad commit. It checkpoints you to the midpoint. You test. You mark good or bad. It narrows down. Repeat until it finds the culprit commit.

# Start the hunt
git bisect start

# Mark current HEAD as bad
git bisect bad

# Mark the last known good commit
git bisect good v2.4.0

# Git checkpoints you to midpoint
# Test. Then mark:
git bisect good  # tests pass
git bisect bad   # tests fail
Enter fullscreen mode Exit fullscreen mode

That's it. That's the whole workflow.

Instead of 47 manual checkouts, I did 6. Six tests. Found the commit that broke everything. It was a configuration change someone made at 11 PM. Added a required field to user validation. Didn't update the test fixtures.

Total time: 20 minutes.

The binary search math is why it works so fast. N commits needs at most log2(N) tests. Forty-seven commits needed 6 tests instead of 47. That's the difference between an hour of waiting and five minutes.

Git bisect sounds intimidating because "binary search" sounds technical. It's not. You run two commands to start, then one command after each test. Comes with git. No plugins needed.

# Cleanup when done
git bisect reset
Enter fullscreen mode Exit fullscreen mode

Top comments (0)