git bisect: Binary Search to Find the Commit That Introduced a Bug
Imagine a bug that definitely wasn't present a month ago, spanning hundreds of commits since then — checking each one individually would be prohibitively slow. `git bisect` solves exactly this problem using a binary search algorithm, letting you pinpoint the exact commit that introduced a regression in a logarithmic, rather than linear, number of steps.
Learning Objectives
- Explain the binary search principle git bisect is built on.
- Run a manual bisect session, marking commits as good or bad.
- Interpret git bisect's final output identifying the offending commit.
- Automate a bisect session using a test script.
Key Terms to Know Before Using git bisect
- git bisect: A command that performs a binary search through commit history to identify the specific commit that introduced a bug or regression.
- Bisect session: The interactive process of starting a bisect, marking commits as good or bad, and letting Git narrow down the search until the offending commit is found.
- Good commit: A commit confirmed to NOT exhibit the bug, marking the known-working boundary of the search.
- Bad commit: A commit confirmed to exhibit the bug, marking the known-broken boundary of the search.
How git bisect Actually Works
The core insight behind `git bisect` is that finding a specific bug-introducing commit is a **binary search problem**: if you know a bug exists now (a 'bad' commit) and know it didn't exist at some earlier point (a 'good' commit), you can efficiently narrow down exactly where it was introduced by repeatedly checking the **midpoint** commit between your current known-good and known-bad boundaries, rather than checking every single commit one by one in order. Each check the bisect performs eliminates roughly half of the remaining candidate commits, meaning even a history spanning hundreds or thousands of commits can typically be narrowed down to the exact culprit in well under 15-20 actual checks (a logarithmic, not linear, relationship with history size — the mathematical reason binary search is dramatically faster than a linear scan).
Starting a bisect session:
```
git bisect start
git bisect bad # the current commit exhibits the bug
git bisect good v1.0.0 # this known-earlier commit/tag did NOT have the bug
```
Git then automatically checks out the midpoint commit between these two boundaries. You test that specific commit (running the application, reproducing the steps that trigger the bug, or whatever verification is relevant) and report the result:
```
git bisect good # if the bug is NOT present at this commit
# or
git bisect bad # if the bug IS present at this commit
```
Git then automatically narrows the search range based on your report and checks out the *next* midpoint, repeating this cycle. After enough good/bad reports, Git eventually announces the exact first bad commit:
```
a1b2c3d is the first bad commit
commit a1b2c3d
Author: Rohit Sharma
Date: ...
feat: refactor discount calculation logic
```
Once you've identified the culprit (and ideally used `git show` from Module 2 to fully understand what it changed), end the session and return to your original branch position:
```
git bisect reset
```
For an even more powerful, fully automated variant, `git bisect run <script>` lets you supply a script (or any command) that exits with a specific status code indicating good or bad automatically — for example, a test script that fails when the bug is present — letting Git run the entire bisect process **completely unattended**, checking out each midpoint, running your script, and interpreting its exit code, without any manual good/bad reporting needed at each step:
```
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run npm test
```
This automated form is dramatically faster for any bug that can be reliably detected by an automated test or script, turning what might otherwise be a long, tedious manual investigation into a single command that runs to completion on its own.
git bisect Binary Search: Visual Walkthrough
Draw a horizontal timeline of 16 commit dots, with the leftmost marked 'GOOD (v1.0.0)' and the rightmost marked 'BAD (current)'. Show the bisect process narrowing down step by step: Step 1 checks the MIDPOINT (commit 8), marked with a result (e.g., 'bad' — shown by shading commits 8-16 as suspect). Step 2 checks the new midpoint of the remaining range (commit 4 of the 1-8 range... wait let's simplify), showing progressively smaller shaded ranges converging on one single commit after about 4 steps total, captioned '16 commits narrowed down in only 4 checks — binary search, not linear scanning.'
git bisect Commands: Quick Reference Table
| Command | Purpose |
|---|---|
| git bisect start | Begins a new bisect session |
| git bisect bad [commit] | Marks a commit (default: current) as exhibiting the bug |
| git bisect good [commit] | Marks a commit as NOT exhibiting the bug, establishing the known-working boundary |
| git bisect run <script> | Fully automates the session using a script's exit code to determine good/bad |
| git bisect reset | Ends the session, returning to your original branch position |
git bisect: Command Syntax and Examples
# Manual bisect session
git bisect start
git bisect bad # current commit has the bug
git bisect good v1.0.0 # this earlier tag did not
# Git checks out a midpoint commit — test it, then report:
git bisect good # (or 'bad', depending on what you observe)
# ... repeat until Git announces the culprit ...
# a1b2c3d is the first bad commit
git show a1b2c3d # inspect exactly what that commit changed (Module 2)
git bisect reset # end the session, return to your original position
# --- Fully automated bisect using a test script ---
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run npm test
# Git automatically checks out each midpoint, runs 'npm test',
# and interprets its exit code (0 = good, non-zero = bad) — no manual input needed
Breaking Down the git bisect Example
The manual session shows the interactive cycle: establish the known-good and known-bad boundaries, then repeatedly test whatever commit Git checks out and report the result, until Git identifies and announces the exact first bad commit. `git show` is then used (revisiting Module 2) to fully understand what that specific commit actually changed. The automated variant demonstrates `git bisect run npm test`, which eliminates all manual reporting entirely — Git runs the test suite at each midpoint automatically and interprets pass/fail directly from the exit code, completing the entire binary search unattended, which is dramatically faster whenever a reliable automated test for the bug already exists.
How git bisect Is Used on Real Engineering Teams
- git bisect is a go-to tool for tracking down mysterious regressions in large, long-lived codebases, especially when the bug's introduction point isn't obvious from recent changes alone.
- Automated bisect runs (git bisect run) combined with a project's existing automated test suite let engineers identify a regression's exact origin in minutes, entirely unattended, rather than manually testing dozens of commits by hand.
- Open-source projects with contributions from many different people particularly benefit from bisect, since it can definitively identify exactly which commit (and therefore which contributor and PR) introduced a specific regression, without requiring deep familiarity with every recent change.
- Performance regressions (a feature becoming measurably slower at some point) are commonly tracked down with bisect combined with an automated benchmark script as the good/bad test, rather than a strict pass/fail correctness test.
git bisect Interview Questions and Answers
Q1. What is the core algorithmic principle behind git bisect, and why is it efficient?
It's a binary search: given a known-good and known-bad commit boundary, bisect repeatedly checks the midpoint between them, eliminating roughly half of the remaining candidate commits with each check. This makes the number of checks needed grow logarithmically rather than linearly with the size of the history, so even hundreds of commits can typically be narrowed down in well under 20 checks.
Q2. Walk through the basic manual steps of a git bisect session.
Start with git bisect start, mark the current commit as bad and a known-earlier commit as good. Git then checks out the midpoint between them; you test it and report git bisect good or git bisect bad. Git repeats this, narrowing the range each time, until it announces the exact first bad commit. Finally, git bisect reset ends the session and returns you to your original branch position.
Q3. What does git bisect run enable, and when is it especially valuable?
It fully automates the bisect process using a supplied script or command's exit code to determine good/bad at each midpoint, without any manual reporting. It's especially valuable when a regression can be reliably detected by an automated test, turning what could be a long manual investigation into a single unattended command.
git bisect Quiz: Test Your Understanding
1. What algorithmic approach does git bisect use to find a bug-introducing commit?
- A linear scan checking every commit in order
- A binary search, repeatedly checking the midpoint between known-good and known-bad boundaries
- A random sampling of commits
- It checks only the most recent commit
Answer: B. A binary search, repeatedly checking the midpoint between known-good and known-bad boundaries
Explanation: Bisect uses binary search, eliminating roughly half the remaining candidate commits with each check, making it dramatically more efficient than checking every commit sequentially.
2. What does git bisect good <commit> indicate during a session?
- That commit exhibits the bug
- That commit does NOT exhibit the bug, establishing a known-working boundary
- That commit should be deleted
- That commit is the final answer
Answer: B. That commit does NOT exhibit the bug, establishing a known-working boundary
Explanation: Marking a commit as 'good' tells bisect that the bug was not present at that point, helping narrow the search range toward where it was actually introduced.
3. What does git bisect run enable?
- Manually testing each commit one at a time with no automation
- Fully automating the bisect process using a script's exit code to determine good/bad at each step
- Permanently deleting bad commits
- Automatically fixing the identified bug
Answer: B. Fully automating the bisect process using a script's exit code to determine good/bad at each step
Explanation: git bisect run lets Git automatically check out each midpoint, run a supplied script or test command, and interpret its exit code, completing the entire search without manual intervention.
Common git bisect Mistakes Beginners Make
- Testing commits in linear order rather than trusting bisect's automatically chosen midpoints, missing out on the efficiency binary search provides.
- Forgetting to run git bisect reset at the end of a session, leaving the repository checked out at an arbitrary historical commit instead of the original branch.
- Reporting a good/bad result inaccurately due to an unreliable or inconsistent manual test, which can mislead the binary search toward the wrong commit.
- Not considering git bisect run when a reliable automated test for the bug already exists, doing unnecessary manual work instead.
git bisect: Exam-Ready Quick Notes
- git bisect: binary search through commit history to find a bug-introducing commit.
- Session flow: bisect start → bisect bad → bisect good <known-working commit> → test each checked-out midpoint → report good/bad → repeat until Git announces the culprit.
- git bisect run <script>: fully automates the session using a script's exit code.
- git bisect reset: ends the session, returning to the original branch position.
git bisect: Key Takeaways
- git bisect applies binary search to bug hunting, finding a regression's exact origin in a logarithmic rather than linear number of checks.
- The manual session flow — start, bad, good, then repeatedly test and report — efficiently narrows down even a very large commit history.
- git bisect run fully automates the process using an automated test's exit code, dramatically speeding up investigation whenever a reliable test exists.
Frequently Asked Questions About git bisect
Q1. What does git bisect do?
It performs a binary search through a project's commit history to efficiently pinpoint exactly which commit introduced a specific bug, by repeatedly testing the midpoint between a known-good and known-bad commit.
Q2. How do I start a bisect session?
Run git bisect start, then mark the current (buggy) commit with git bisect bad, and mark an earlier commit you know didn't have the bug with git bisect good <commit>. Git will then guide you through testing successive midpoint commits.
Q3. How do I use git bisect once Git checks out a commit for me to test?
Test that specific commit for the presence of the bug (run the app, reproduce the steps that trigger it, etc.), then report the result with git bisect good or git bisect bad, and Git will automatically check out the next midpoint to test.
Q4. Can I automate the entire bisect process?
Yes, using git bisect run <script or command>. If you have a script or test command that reliably exits with a specific status when the bug is present, Git will automatically run it at each midpoint and complete the entire search unattended.
Q5. What should I do once git bisect has identified the offending commit?
Use git show on that commit's hash to see exactly what it changed, then run git bisect reset to end the session and return your repository to the branch position you started from.
Summary
`git bisect` performs a binary search through commit history to pinpoint exactly which commit introduced a bug, dramatically more efficient than manually checking every commit sequentially. A session begins by marking the current commit as `bad` (exhibiting the bug) and an earlier commit as `good` (not exhibiting it); Git then repeatedly checks out the midpoint between the known boundaries, prompting you to test it and report `git bisect good` or `git bisect bad`, narrowing the search range each time until Git announces the exact first bad commit. `git bisect reset` ends the session, returning to your original branch position. For an even faster, fully automated approach, `git bisect run <script>` lets a script's exit code automatically determine good/bad at each midpoint, completing the entire search unattended whenever a reliable automated test for the bug exists.