Git bisect finds bugs by binary search through history, but sometimes you need to reset or recover when bisect gets stuck or you find the wrong commit.
The Error
During bisect session:
git bisect resetYou see:
fatal: Could not parse object 'refs/bisect/bad'
fatal: bisect run failed: exit code 128Or:
git bisect startfatal: There is already a bisect session
fatal: You need to run git bisect reset firstOr:
git bisect bad abc1234fatal: Some revisions not in the given bad-good range
fatal: bisect: bad revisionOr bisect stuck at wrong commit:
``bash
git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
abc1234 is the first bad commitBut the bug exists before this commit.
Why Bisect Reset Fails
Common causes:
- Corrupt bisect refs - refs/bisect/* damaged or missing
- Missing commits - Commit specified was deleted or lost
- Stuck bisect state - Previous session not properly cleaned
- Wrong good/bad boundaries - Bad commit is ancestor of good
- Detached HEAD issues - Bisect leaves HEAD detached
- Uncommitted changes - Dirty worktree during bisect
Diagnosis Steps
Check bisect status:
``bash
git bisect log
Shows bisect history:
``
git bisect start
git bisect bad abc1234
git bisect good def5678
# Status: bisecting, 4 revisions to test
Check bisect refs:
``bash
git for-each-ref refs/bisect/
ls .git/refs/bisect/
Check HEAD state:
``bash
git status
cat .git/HEAD
Check for bisect files:
``bash
ls .git/BISECT_* 2>/dev/null
Files like BISECT_LOG, BISECT_NAMES, BISECT_START.
Verify commit exists:
``bash
git cat-file -t abc1234
Solution 1: Force Reset Bisect
Standard reset fails, force cleanup:
git bisect reset --forceOr manually: ```bash # Remove bisect refs git for-each-ref --format='%(refname)' refs/bisect/ | while read ref; do git update-ref -d "$ref" done
# Remove bisect files rm -f .git/BISECT_LOG .git/BISECT_NAMES .git/BISECT_START .git/BISECT_TERMS
# Return to original branch git checkout main # or your branch ```
Solution 2: Reset to Specific Branch
Reset and checkout specific branch:
git bisect reset mainOr:
``bash
git bisect reset HEAD~5
Returns to specified commit after bisect.
Solution 3: Fix Missing Bisect Refs
If refs/bisect/bad or refs/bisect/good missing:
ls .git/refs/bisect/Check bisect log for references:
``bash
cat .git/BISECT_LOG
Manually recreate refs:
``bash
# Find from log
git update-ref refs/bisect/bad abc1234
git update-ref refs/bisect/good def5678
Then reset:
``bash
git bisect reset
Solution 4: Abort Bisect with Dirty Worktree
Uncommitted changes block bisect:
git bisect reseterror: Your local changes would be overwritten by checkoutStash changes:
``bash
git stash push -m "bisect work"
git bisect reset
git stash pop
Or force reset:
``bash
git checkout -- .
git bisect reset
Solution 5: Fix Wrong Bisect Result
Bisect identifies wrong commit:
git bisect goodabc1234 is the first bad commitBut bug exists in earlier commits.
Continue bisect to find earlier:
``bash
git bisect reset
git bisect start
git bisect bad <earlier-bad-commit>
git bisect good <good-commit>
Or mark as skip:
``bash
git bisect skip abc1234
Skip commits that are hard to test.
Solution 6: Recover After Accidental Reset
Reset before marking the culprit:
git bisect resetOops! You didn't note the bad commit.
Check bisect log:
``bash
cat .git/BISECT_LOG
Still contains history.
Check reflog:
``bash
git reflog
Look for bisect entries.
Restart bisect with known range:
``bash
git bisect start
git bisect bad <last-known-bad>
git bisect good <last-known-good>
Solution 7: Fix Bisect Terms
Using custom bisect terms:
git bisect start --term-old fixed --term-new broken
git bisect broken
git bisect fixedReset with terms:
``bash
git bisect reset --term-old fixed --term-new broken
Or just:
``bash
git bisect reset
Terms reset automatically.
Solution 8: Handle Bisect with Run Script
Automated bisect gets stuck:
git bisect run ./test-script.shScript returns unexpected codes.
Check script requirements:
``bash
# Script should return:
# 0 - if good (old term)
# 1-127 (except 125) - if bad (new term)
# 125 - if skip (cannot test)
Reset after failed run:
``bash
git bisect reset
Fix script and restart:
``bash
git bisect start
git bisect bad bad-commit
git bisect good good-commit
git bisect run ./fixed-test-script.sh
Solution 9: Complete Manual Reset
When all else fails:
```bash # Full cleanup rm -rf .git/refs/bisect/ rm -f .git/BISECT_LOG .git/BISECT_NAMES .git/BISECT_START .git/BISECT_TERMS
# Return to known state git checkout main
# Verify cleanup git bisect log # Should fail: "We are not bisecting" git status # Should show clean state ```
Verification
Verify bisect ended:
``bash
git bisect log
Should return:
``
We are not bisecting.
Verify on proper branch:
``bash
git status
Should show:
``
On branch main
nothing to commit, working tree clean
Verify no bisect refs remain:
``bash
git for-each-ref refs/bisect/
Should return nothing.
Verify HEAD:
``bash
cat .git/HEAD
Should show ref: refs/heads/main not bisect ref.
Bisect Commands Reference
```bash # Start bisect git bisect start [<bad> [<good>...]]
# Mark commits git bisect bad [<rev>] git bisect good [<rev>] git bisect skip [<rev>...] # Skip hard-to-test commits
# View status git bisect log git bisect visualize git bisect view
# Automated bisect git bisect run <script>
# Reset bisect git bisect reset [<branch>]
# Custom terms git bisect start --term-old=<term> --term-new=<term> ```
Best Practices
Note the bad commit before resetting:
``bash
# When bisect finds culprit
git bisect log | tail -5 # Note the commit
git show abc1234 # Examine the commit
# Then reset
git bisect reset
Use bisect log for documentation:
``bash
git bisect log > bisect-history.txt
Save bisect history for reference.
Skip untestable commits:
``bash
git bisect skip
Don't force testing broken builds.
Test before marking:
``bash
# Test current commit
./run-tests.sh
# Based on result
git bisect good # or bad
Start with tight range:
``bash
git bisect start v2.0 v1.5
Narrow range speeds bisect.
Common Scenarios
Scenario: Bisect for regression in CI
```bash git bisect start git bisect bad HEAD # Current broken git bisect good v1.0 # Last known good
# Automated testing git bisect run "npm test && echo good || echo bad" ```
Scenario: Find where feature was added
git bisect start --term-old without --term-new with
git bisect with HEAD
git bisect without v1.0
# Check each commit for feature presenceScenario: Bisect takes too long
# Skip builds that can't compile
git bisect skip
# Or narrow the range
git bisect reset
git bisect start bad~100 good~50Bisect State Files
.git/
├── BISECT_LOG # Bisect operation log
├── BISECT_NAMES # Good/bad commit names
├── BISECT_START # Original HEAD before bisect
├── BISECT_TERMS # Custom terms if used
└── refs/
└── bisect/
├── bad # Current bad boundary
├── good # Current good boundary
└── good-* # All good refsUnderstanding these helps with manual recovery.