Find somethingAlways fixable

Find the exact commit that introduced a bug

How do I find which commit broke my code?

Short answer

git bisect binary-searches your history. Tell it one commit that works and one that doesn't; it checks out the midpoint and asks you to test, halving the range each time. With git bisect run it tests automatically and names the guilty commit unattended.

quick fix
git bisect start
git bisect bad
git bisect good v1.2.0

Start bisecting between a known-good tag and the broken present

Does this match your situation?

  • Something worked last week and doesn't now.
  • There are too many commits to review by hand.
  • A test started failing and nobody knows which change caused it.

Step-by-step fix

  1. Find a commit where it definitely worked

    You need one known-good reference point. A release tag is ideal; otherwise pick a commit from before the problem appeared and verify it manually.

    step 1
    git log --oneline --since='3 weeks ago'
    git tag --sort=-v:refname | head -5
    
  2. Start the bisect

    Mark the current state bad and the old commit good. Git immediately checks out a commit halfway between them for you to test.

    step 2
    git bisect start
    git bisect bad                # current commit is broken
    git bisect good v1.2.0        # this tag was fine
    
  3. Test and answer, repeatedly

    Build or run whatever demonstrates the bug, then tell Git the verdict. Each answer halves the remaining range, so even a thousand commits resolve in about ten rounds.

    step 3
    # test the checked-out commit, then:
    git bisect good     # this one works
    # or
    git bisect bad      # this one is broken
    # or
    git bisect skip     # can't test this one (won't build)
    

    Git prints how many revisions are left and roughly how many steps remain.

  4. Automate it with a test command

    If you can express the bug as a command that exits non-zero when broken, hand it to Git and walk away. This is by far the most powerful form of bisect.

    step 4
    git bisect start HEAD v1.2.0
    git bisect run npm test
    
    # any command works:
    git bisect run ./scripts/check.sh
    git bisect run pytest tests/test_save.py
    
  5. Read the verdict and reset

    Git names the first bad commit and shows its diff. Always reset afterwards to return to the branch you started on.

    step 5
    # Git prints: a1b2c3d is the first bad commit
    git show a1b2c3d
    git bisect reset
    

Why this works

Because every commit is a complete, buildable snapshot, any commit in your history can be checked out and tested in isolation. That turns 'which change broke this' into a sorted-search problem, and binary search over n commits takes about log₂(n) tests — 1024 commits need only ten. git bisect maintains the search state for you, and bisect run automates the answering step by interpreting your command's exit code.

How to stop it happening again

  • Keep commits small and atomic so bisect points at a change you can actually read.
  • Ensure every commit builds — never commit a broken intermediate state.
  • Run CI on every push so breakages are caught within one commit of being introduced.

Commands used in this guide

git bisect

Binary-search your history to find the exact commit that introduced a bug.

git log

Browse commit history with as much or as little detail as you want.

git blame

Show which commit and author last touched every line of a file.

git show

Display a single commit, tag or file-at-a-commit in full.

Still stuck?

Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.

Browse all guides →

Frequently asked questions

How does git bisect work?

It performs a binary search over your commit history. You mark one commit good and one bad; Git checks out the midpoint and you report the result. Each answer halves the search range, so it narrows a thousand commits down to one in roughly ten steps.

Can git bisect run automatically?

Yes. git bisect run <command> executes your command at each step and interprets the exit code — zero means good, non-zero means bad. Pair it with your test suite and Git finds the offending commit with no further input from you.

What if a commit in the middle won't build?

Use git bisect skip. Git excludes that commit and picks another nearby one. If a whole region is unbuildable, bisect may end up reporting a range of candidates instead of a single commit.

How do I stop a bisect?

git bisect reset returns you to the branch and commit you were on before starting. Always run it when you're done — otherwise you're left on a detached HEAD partway through history.

Related rescue guides

← All Git Rescue guides