Git Bisect
The git bisect command uses a binary search algorithm to find the specific commit that introduced a bug. Instead of manually checking every commit in the history, Git cuts the search space in half at each step — making the process fast and efficient even in repositories with thousands of commits.
Real-life analogy: Imagine a book with 1000 pages and the goal is to find the first page where a certain word appears. Rather than starting at page 1, open the book at page 500. If the word is not there yet, check page 750. If the word is there by page 750, check page 625, and so on. Each step halves the search range. This is binary search — and it is exactly how git bisect works.
How Binary Search Works in Git Bisect
Commits: 1 ─ 2 ─ 3 ─ 4 ─ 5 ─ 6 ─ 7 ─ 8 ─ 9 ─ 10
↑
Bug introduced here (unknown)
Known: commit 1 = good (no bug), commit 10 = bad (has bug)
Step 1: Test commit 5 → Good → Bug is between 5 and 10
Step 2: Test commit 7 → Bad → Bug is between 5 and 7
Step 3: Test commit 6 → Bad → Bug is between 5 and 6
Step 4: Test commit 5 → Good → Bug introduced in commit 6!
In just 4 steps, the exact bad commit is found from 10 commits. For 1000 commits, only about 10 steps are needed.
Manual Bisect Workflow
Step 1 — Start the Bisect Session
git bisect startStep 2 — Mark the Current (Broken) State as Bad
git bisect badThis tells Git that the current commit has the bug.
Step 3 — Mark a Known Good Commit
Find a commit hash from the past when everything was working. Check the log:
git log --oneline
# a3f92b1 Latest commit (broken)
# b7c3d45 2 days ago
# c1a2b3c 1 week ago ← This was working
git bisect good c1a2b3c
Git now knows the range: good at c1a2b3c, bad at current. It checks out the middle commit automatically.
Step 4 — Test Each Commit
For each commit Git checks out, test whether the bug is present. Then tell Git the result:
# If the bug IS present:
git bisect bad
# If the bug is NOT present:
git bisect good
Git keeps narrowing down until it finds the exact commit that introduced the bug.
Step 5 — Result
b7c3d45 is the first bad commit
commit b7c3d45
Author: Priya Sharma <priya@example.com>
Date: Sun Oct 8 11:15:00 2023
Update user authentication logic
Step 6 — End the Bisect Session
git bisect resetThis returns the repository to the original branch and commit before the bisect started.
Full Practical Example
# 1. A bug exists in the latest version. Start bisect.
git bisect start
# 2. Current commit is broken
git bisect bad
# 3. Last week's code was fine
git bisect good v1.5.0 # Can use a tag
# Git checks out a commit in the middle:
# "Bisecting: 12 revisions left to test after this"
# 4. Test: Does the bug exist? Yes.
git bisect bad
# Git checks out the next middle commit
# 5. Test: Does the bug exist? No.
git bisect good
# Git checks out the next middle commit
# 6. Test: Does the bug exist? Yes.
git bisect bad
# Result: "d4e5f6g is the first bad commit"
# 7. Clean up
git bisect reset
Automated Bisect
If there is a script or test that automatically determines whether the code is good or bad, the entire bisect can run without any manual steps. Git runs the script at each commit:
git bisect start
git bisect bad HEAD
git bisect good v1.5.0
# Run automated test script for every step
git bisect run npm test
The script should exit with 0 (success) if the commit is good and exit with a non-zero code if the commit is bad. Git handles the rest automatically and reports the first bad commit.
Skipping a Commit
Sometimes a commit cannot be tested (build fails, unrelated issue). It can be skipped:
git bisect skipGit will continue with other commits near this one.
View the Bisect Log
git bisect logShows all the good/bad decisions made during the current bisect session.
When is git bisect Most Useful?
- A bug appeared but there is no idea which of the last 50+ commits caused it
- A performance regression appeared somewhere in history
- A feature that used to work has stopped working and the breaking commit needs to be found
- Debugging in large codebases where manual code inspection would take too long
Summary
git bisect uses binary search to efficiently find the commit that introduced a bug. It can search hundreds of commits in just a handful of steps. The process is: git bisect start → mark the bad commit → mark a known good commit → test each midpoint and mark as good or bad → Git identifies the first bad commit → git bisect reset. Automated bisect with a test script is the most powerful usage.
