This error occurs when you have uncommitted changes in your working directory and try to run git bisect. Git bisect needs to checkout different commits during the binary search process, and local modifications would conflict with these checkouts.
Git bisect is a powerful debugging tool that uses binary search to find the commit that introduced a bug. When you run `git bisect start`, Git needs to checkout different commits between a known "good" and "bad" state to narrow down the problematic commit. The "fix your working tree" error appears because Git cannot safely checkout other commits when you have uncommitted changes. These changes would either be lost during the checkout or cause conflicts. This is a safety mechanism to protect your work. The working tree refers to your actual files on disk as opposed to what's stored in Git's database. When it's "dirty" (has uncommitted changes), Git prevents operations that would overwrite or lose those changes.
First, see exactly what changes are preventing bisect:
git statusThis shows:
- Changes not staged for commit: Modified tracked files
- Changes to be committed: Staged changes waiting for commit
- Untracked files: New files Git doesn't know about
Identify which category your changes fall into before proceeding.
The safest option is to stash your changes, which saves them temporarily:
git stash push -m "WIP: changes before bisect"This saves both staged and unstaged changes. After bisect completes, restore them:
git stash popInclude untracked files if needed:
git stash push -u -m "WIP: all changes before bisect"The -u flag includes untracked files in the stash.
Now that your working tree is clean, begin bisecting:
git bisect start
git bisect bad HEAD # Current commit has the bug
git bisect good <known-good-commit> # Replace with a commit hash or tagGit will checkout a commit halfway between good and bad. Test it, then mark:
git bisect good # If this commit doesn't have the bug
# OR
git bisect bad # If this commit has the bugRepeat until Git identifies the first bad commit.
When bisect finds the problematic commit, it displays the result. End the session:
git bisect resetThis returns your repository to the branch you were on before bisecting. Now restore your stashed changes:
git stash popIf you have multiple stashes, list them first:
git stash list
git stash pop stash@{0} # Apply specific stashIf your changes are substantial, commit them to a temporary branch instead of stashing:
git checkout -b temp-work-branch
git add .
git commit -m "WIP: temporary commit for bisect"
git checkout main # or your original branchAfter bisecting:
git checkout temp-work-branch
git reset HEAD~1 # Undo the commit, keep changes
git checkout main
git branch -D temp-work-branch # Clean upIf you don't want to interrupt your current work at all, create a separate working directory:
git worktree add ../bisect-worktree HEAD
cd ../bisect-worktree
git bisect start
git bisect bad HEAD
git bisect good <known-good-commit>This creates a linked working tree where you can bisect independently. Your main working directory remains untouched.
Clean up after bisecting:
cd ..
rm -rf bisect-worktree
git worktree pruneIf a previous bisect session wasn't cleaned up properly:
git bisect resetIf that fails, manually remove bisect state:
rm -rf .git/BISECT_*
git checkout <your-branch>Then stash/commit your changes and start fresh.
### Automating Bisect with Scripts
For complex tests, automate bisect with a script:
git bisect start HEAD <good-commit>
git bisect run ./test-script.shYour script should return:
- Exit code 0: Commit is good
- Exit code 1-127 (except 125): Commit is bad
- Exit code 125: Skip this commit (can't test)
### Handling Modifications During Bisect
If your test requires applying patches or modifications to each commit:
git bisect run sh -c 'patch -p1 < ../fix.patch && make && make test; ret=$?; git reset --hard; exit $ret'The git reset --hard undoes the patch before moving to the next commit.
### Git Worktree Benefits
Using git worktree for bisect has several advantages:
- Continue working in your main directory
- No need to stash or commit changes
- Bisect refs are isolated per worktree
- Can run bisect in the background
### Bisect with Path Limiting
If the bug is likely in specific files, limit bisect's scope:
git bisect start -- src/auth/Git will only consider commits that touched files in src/auth/.
### Preserving Bisect State
If you need to pause bisecting, the state is preserved. You can see where you are:
git bisect logTo replay a bisect session from a log:
git bisect replay bisect.logwarning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server