How to Find a Bug with `git bisect` (Binary Search Debugging)
Finding a bug is like detective work-except the crime scene is your code, and the suspect is one of your last 200 commits. You know the code worked last week, and you know it's broken now, but finding the exact moment it failed can take hours of manual checking.
Enter git bisect. It uses a binary search algorithm to find the offending commit with mathematical efficiency. Instead of checking every commit, it cuts the search area in half every single time.
π How It Works: The Binary Searchβ
If you have 100 commits to check, a manual search might take 100 tries. git bisect will find the bug in no more than 7 steps.
- You tell Git a "Bad" point (where the bug exists).
- You tell Git a "Good" point (a time in history when the code worked).
- Git checks out a commit in the middle.
- You test the code. Is it broken?
- Broken: Tell Git
git bisect bad. - Working: Tell Git
git bisect good.
- Git repeats until it points at the exact "First Bad Commit."
π» The Step-by-Step Guideβ
I've put the workflow into this block so you can copy the commands as you go through your terminal.
# 1. Start the process
git bisect start
# 2. Mark the current version as bad (assuming you're on the broken branch)
git bisect bad
# 3. Find a commit from the past where you know it worked.
# You can use a Tag, a Branch name, or a Commit Hash.
git bisect good v1.0.4 # Or use a hash like 'git bisect good abc1234'
# --- Git will now check out the middle commit ---
# 4. Test your app. If it's still broken:
git bisect bad
# 5. If it works perfectly:
git bisect good
# --- Repeat step 4 or 5 until Git says: ---
# "abc1234... is the first bad commit"
# 6. Once you've found the bug, return to your original branch:
git bisect reset
π Pro Tip: git bisect run (Full Automation)β
If you have a Python script or a unit test (like pytest) that can detect the bug automatically, you don't even have to manually check the code. Git will do it all for you while you go get a coffee.
# Assuming you have a test file: test_bug.py
# If the test exits with 0, it's 'good'. If it exits with 1, it's 'bad'.
git bisect start HEAD v1.0.0
git bisect run python test_bug.py
Git will cycle through the commits, run your script on each one, and stop when it finds the failure. It's like magic.
π Manual vs. Bisect Efficiencyβ
| Number of Commits | Manual Checks (Worst Case) | Bisect Checks (Worst Case) |
|---|---|---|
| 10 | 10 | 4 |
| 100 | 100 | 7 |
| 1,000 | 1,000 | 10 |
| 10,000 | 10,000 | 14 |
π Sources & Technical Refsβ
- [1.1] Git SCM: git-bisect - The official documentation on binary search debugging.
- [2.1] Microsoft Learn: Debug with git bisect - A guide on using bisect in enterprise environments.
- [3.1] Real Python: Testing your Code - How to write the simple scripts needed for
git bisect run.
π Troubleshooting Tipβ
If you reach a commit that can't be tested (e.g., it has a different bug that prevents the app from starting), you can use git bisect skip. Git will try to find a nearby commit to test instead.
