Skip to content

Git Bisect: Finding the Commit That Broke Everything

DodaTech Updated 2026-06-22 5 min read

In this tutorial, you'll learn about Git Bisect: Finding the Commit That Broke Everything. We cover key concepts, practical examples, and best practices.

Git bisect performs a binary search through commit history to find the exact commit that introduced a bug in log2(N) steps instead of checking every commit manually.

In this tutorial, you'll learn Git bisect — a powerful tool that uses binary search to find the exact commit that introduced a bug. Instead of manually checking dozens of commits, bisect narrows it down in logarithmic time. By the end, you'll run manual and automated bisect sessions and integrate bisect into your debugging workflow.

flowchart TD
  A[Mark bad commit: HEAD] --> B[Mark good commit: old known-working]
  B --> C[Bisect: checkout middle commit]
  C --> D{Test the commit}
  D -->|Good| E[Mark as good]
  D -->|Bad| F[Mark as bad]
  E --> G{More commits?}
  F --> G
  G -->|Yes| C
  G -->|No| H[Found first bad commit]

Starting a Bisect Session

# Start bisect
git bisect start

# Mark current HEAD as broken
git bisect bad

# Mark a known-good commit (e.g., from a tag)
git bisect good v1.0.0

Expected output:

Bisecting: 8 revisions left to test after this (roughly 3 steps)
[c3a2b1f] Add login feature

Git checks out a commit midway through history for you to test.

Testing Each Step

At each bisect step, test whether the bug exists:

# If the bug is present:
git bisect bad

# If the bug is not present:
git bisect good

Git continues narrowing down:

Bisecting: 4 revisions left to test after this (roughly 2 steps)
[9d8e7f6] Update API endpoint

After a few more steps:

c1b2a3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9 is the first bad commit
commit c1b2a3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9
Author: Developer Name
Date:   Mon Jun 15 14:30:00 2026 +0000

    Fix login bug

Automated Bisect

For bugs with automated tests, let Git run bisect automatically:

git bisect start HEAD v1.0.0
git bisect run npm test

Or with a custom script:

git bisect start HEAD v1.0.0
git bisect run python -m pytest tests/test_login.py

Expected output:

running  python -m pytest tests/test_login.py
running  python -m pytest tests/test_login.py
c1b2a3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9 is the first bad commit

The git bisect run command automates the entire process. Your script or test command must exit with 0 for "good" and non-zero for "bad".

Bisect with Skip

Some commits may be untestable (merge commits, broken builds). Skip them:

git bisect skip

Or skip a range of commits:

git bisect skip a1b2c3d..e5f6g7h

Visualizing Bisect Progress

git bisect log

Expected output:

git bisect start
# bad: [a1b2c3d] Latest commit
git bisect bad a1b2c3d
# good: [e5f6g7h] Release v1.0
git bisect good e5f6g7h
# good: [b3c4d5e] Add config file
git bisect good b3c4d5e
# first bad commit: [c1b2a3d] Fix login bug
git bisect bad c1b2a3d

Ending a Bisect Session

git bisect reset

This returns your working directory to the original branch.

Common Errors

Error Cause Fix
Some good refs are not ancestors of the bad ref Good commit is not an ancestor Ensure good commit is older than bad
You need to start by "git bisect start" Bisect not initialized Run git bisect start first
You need at least one good and one bad commit Not both states defined Mark both good and bad commits
Cannot bisect: no commits Only one commit Bisect requires a range
Bisect run failed: exit code 127 Script not found Use full path to script
Skipped commit cannot be tested Build broken at that point Use git bisect skip
detached HEAD during bisect Normal bisect behavior Use git bisect reset to return
rebase in progress when starting bisect Existing rebase Finish or abort rebase first

Practice Questions

What is Git bisect?

Git bisect uses binary search to find the exact commit that introduced a bug. You mark one good (working) commit and one bad (broken) commit, and Git walks through the middle commits, asking you to test each one until it isolates the first bad commit.

How many steps does bisect take?

Binary search means bisect checks log2(N) commits. With 1000 commits, it takes about 10 steps. With 1 million commits, about 20 steps. This makes bisect extremely efficient even for large repositories.

Can I automate Git bisect?

Yes. Use git bisect run <script> where the script returns exit code 0 for "good" and non-zero for "bad". This is ideal when you have automated tests that reproduce the bug. Git runs the script at each step automatically.

What happens if I cannot test a commit?

Use git bisect skip to skip commits that can't be tested — for example, because the build is broken or the tests don't apply. Git tries to find an adjacent commit to test instead.

How do I return to normal after bisect?

Run git bisect reset. This ends the bisect session and checks out the branch you were on before starting. If you forget, git bisect reset works from any state

Challenge

Create a repository with 20 commits. Introduce a bug in commit 12. Use git bisect to find the exact commit that introduced the bug. Then write a Python script that reproduces the bug and use git bisect run to automate the search. Verify you found the correct commit.

Real-World Task

In a production application, a bug was introduced sometime in the last 50 commits. Write an automated test that reproduces the bug. Use git bisect run with that test to identify the exact commit. Once found, use git revert to create a fix commit. Push the fix and the revert. This binary search technique is regularly used at DodaTech when debugging Durga Antivirus Pro's scanning engine across hundreds of commits.


Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro