Git Bisect
# Manual bisectinggit bisect startgit bisect bad # Current commit has the buggit bisect good v1.0.0 # Known good commit# Test your code, then mark each commit:git bisect good # or 'git bisect bad'git bisect reset # When done
# Automated bisectinggit bisect start HEAD v1.0.0git bisect run npm test # Or any test scriptgit bisect resetThe concept
Section titled “The concept”Git bisect - Use binary search to find the commit that introduced a bug.
~ Git Documentation
git bisect <subcommand> <options>Git bisect uses binary search to efficiently find the commit that introduced a bug. Instead of manually checking each commit one by one, bisect divides the commit history in half with each step, greatly reducing the time needed to locate problematic changes.
How it works
Section titled “How it works”Git bisect uses binary search to find the problematic commit:
- Mark a “bad” commit (where the bug exists)
- Mark a “good” commit (where the bug doesn’t exist)
- Git checks out the commit in the middle
- You test and mark it as “good” or “bad”
- Repeat until the culprit is found
With each step, you eliminate half of the remaining commits. For 100 commits, you’ll find the bug in ~7 steps (log₂(100) ≈ 6.64).
Basic usage
Section titled “Basic usage”Manual bisecting
Section titled “Manual bisecting”# Start the bisect sessiongit bisect start
# Mark the current commit as bad (bug exists here)git bisect bad
# Mark a known good commit (use commit hash or tag)git bisect good v1.2.0# orgit bisect good a1b2c3d
# Git checks out a commit in the middle# Test your code, then mark it:git bisect good # if bug doesn't exist# orgit bisect bad # if bug exists
# Repeat until Git finds the first bad commit# Git will output something like:# "abc1234 is the first bad commit"
# When done, return to your original branchgit bisect resetAutomated bisecting
Section titled “Automated bisecting”The real power of git bisect comes when you automate the testing process.
# Run bisect with a test scriptgit bisect start HEAD v1.0.0git bisect run npm testGit marks commits based on your script’s exit code:
- Exit code 0 = good commit
- Exit code 1-127 (except 125) = bad commit
- Exit code 125 = skip this commit
Example test script
Section titled “Example test script”#!/bin/bashnpm installnpm run buildnpm test -- --testNamePattern="user validation"
# Exit code 0 = pass (good), 1 = fail (bad)chmod +x test-for-bug.shgit bisect start HEAD v1.0.0git bisect run ./test-for-bug.shUseful commands
Section titled “Useful commands”# Skip a commit that can't be testedgit bisect skip
# View bisect historygit bisect log
# Visualize remaining commitsgit bisect visualize- Use tags/branches instead of commit hashes:
git bisect good v1.0.0 - Keep tests fast: Run only what’s necessary to verify the bug
- Automate when possible: Automated bisecting is faster and less error-prone
- Ensure deterministic tests: Flaky tests will give incorrect results
- Always reset: Run
git bisect resetwhen done to avoid detached HEAD
Resources
Section titled “Resources”Official Git documentation on git bisect
Git SCM book chapter on debugging with Git
Julia Evans’ zine on git bisect