Concepts
Git Bisect Deep Dive
Master Git bisect's binary search, automation with run mode, visualization, and large repo optimization.
- Readers who want the history model before advanced commands
- A basic sense that commits are not just a file list
- Treating a concepts page like a command how-to
What you will learn
- Understand the core purpose of Git Bisect Deep Dive
- Master the basic usage and common options of Git Bisect Deep Dive
- Master Git bisect's binary search, automation with run mode, visualization, and large repo optimization.
- Understand key concepts: Overview
- Know when to use this feature and when to avoid it
Start with a problem
You've encountered a conceptual question while using Git — you roughly know what it means, but you're not entirely sure about its precise definition and boundaries.
Overview
git bisect uses binary search to find the commit that introduced a bug. It turns O(n) linear search into O(log n) — the core tool for regression hunting.
Basic Workflow
# 1. Start bisect
git bisect start
# 2. Mark bad commit (current usually broken)
git bisect bad
# 3. Mark good commit (known working)
git bisect good v1.0.0
# 4. Git checks out midpoint, test and mark
git bisect good # or git bisect bad
# 5. Repeat until found
# Output: first bad commit
# 6. Clean up
git bisect reset
Internal Mechanics
Binary Search Algorithm
flowchart TD
A[Range: good...bad] --> B[Calc midpoint]
B --> C{Test midpoint}
C -->|Pass| D[good = midpoint]
C -->|Fail| E[bad = midpoint]
D --> F[Range shrinks]
E --> F
F --> G{Range > 1?}
G -->|Yes| B
G -->|No| H[Found first bad]
Git maintains a commit set, excluding half each step. Max steps: log2(N).
Skipping Commits
# Current commit untestable (e.g., won't build)
git bisect skip
# Skip a range
git bisect skip v1.1..v1.2
Automation (git bisect run)
Basic Usage
# Write test script (0=good, 1-127=bad, 125=skip)
cat > test.sh << 'EOF'
#!/bin/bash
make test
exit $?
EOF
chmod +x test.sh
# Fully automatic
git bisect run ./test.sh
Script Contract
| Exit Code | Meaning |
|---|---|
| 0 | Test passed (good) |
| 1-127 | Test failed (bad) |
| 125 | Untestable (skip) |
| 128+ | Script error, abort |
Complex Example
#!/bin/bash
# test-bisect.sh
set -e
# Build
if ! make -j$(nproc) 2>/dev/null; then
exit 125 # Build fail, skip
fi
# Run specific test
if ./run-test-suite --filter=regression_login; then
exit 0
else
exit 1
fi
git bisect run ./test-bisect.sh
Visualization & Analysis
View Progress
# Show current state
git bisect log
# Visualize remaining candidates
git bisect visualize
# Opens gitk with remaining candidates
Manual Inspection
# See current commit under test
git log --oneline -1
# Count remaining candidates
git bisect log | grep -c "bisect"
Result Analysis
# On completion shows:
# 1a2b3c4 (first bad commit)
# Author: ...
# Date: ...
# Commit message
# Save log for postmortem
git bisect log > bisect-log.txt
Large Repo Optimization
Limit Search Scope
# Search only specific path
git bisect start -- path/to/subsystem
# Exclude paths
git bisect start -- . ':!vendor/' ':!third_party/'
Pre-skip Irrelevant Commits
# Skip chore commits
git bisect skip $(git log --oneline --grep="^chore:" --format=%H)
# Skip bot commits
git bisect skip $(git log --oneline --author="bot" --format=%H)
Parallel Testing (Experimental)
# Use worktrees to test multiple candidates in parallel
git worktree add ../test-1 $(git rev-parse HEAD~10)
git worktree add ../test-2 $(git rev-parse HEAD~20)
# Run tests in parallel across worktrees
Advanced Techniques
Multiple Good/Bad Marks
# Mark multiple good
git bisect good v1.0 v1.1 v1.2
# Mark multiple bad
git bisect bad HEAD HEAD~1 HEAD~2
Semantic Terms
# Custom terminology
git bisect start --term-new=broken --term-old=working
git bisect broken
git bisect working v1.0
Replay Bisect Log
# Record
git bisect log > bisect.log
# Replay later (reproduce process)
git bisect replay bisect.log
Common Scenarios
Scenario 1: Performance Regression
git bisect run ./bench.sh
# bench.sh: runs benchmark, compares threshold
Scenario 2: API Breakage
git bisect run ./api-compat-check.sh
# Checks public API signatures
Scenario 3: Build Failure
git bisect run ./build.sh
# Build fail returns 125
Best Practices
- Write reusable test scripts — commit to repo, CI can use them too
- Use
skipfor untestable commits — avoids polluting results - Limit search paths — 10x+ speedup in large monorepos
- Save
bisect log— postmortem, audit, team sharing - Automate in CI — nightly bisect to catch regressions early
Try it yourself
- Practice the git-bisect-deep command in a test repository and observe state changes before and after
- Experiment with different options and compare the output differences
- Simulate a real scenario where you would need to use this, and walk through the full process
Continue Learning
commands/git-bisect— git bisect referenceworkflows/bisect-regression-triage-workflow— Regression triage workflowinternals/commit-graph— Commit graph accelerates bisectconcepts/git-rebase-deep— Git Rebase Deep Dive