# Fix Git Bisect Skip Marking Bad Commit Incorrectly
You use git bisect to find the commit that introduced a bug, but at some point in the process you encounter a commit that cannot be tested (fails to build, missing dependency, unrelated crash). You mark it as skip:
git bisect skipAfter several skips, bisect gives up:
There are only 'skip'ped commits left to test.
The first bad commit could be any of:
abc1234
def5678
901abcd
We cannot bisect more!Git cannot narrow down the bad commit because too many commits in the range were skipped.
Understanding How Bisect Works
Git bisect uses binary search to find the first bad commit:
Good commit A -------------------- Bad commit Z
|
Bisect picks M
|
You mark M as good or bad
|
Range halvesWhen you skip, Git cannot eliminate half the search space. Multiple skips make the search space too small to be useful.
Step 1: Avoid Skipping When Possible
Before skipping, try to determine if the commit can be tested with modifications:
# If the build fails due to a missing dependency
# Install the dependency and test manually
sudo apt install missing-dependency
make test
# Then mark as good or bad manually
git bisect good # or git bisect badIf you can determine the status manually, you avoid the skip problem.
Step 2: Use Bisect Run for Automated Testing
The most reliable bisect workflow uses git bisect run with a script that returns the correct exit code:
```bash #!/bin/bash # bisect-test.sh
# Build the project make || exit 125 # Skip if build fails
# Run the test ./test-bug.sh exit $? # 0 = good, 1 = bad ```
Then run:
git bisect start
git bisect bad HEAD
git bisect good v1.0
git bisect run ./bisect-test.shExit codes:
- 0 -- Commit is good
- 1-127 -- Commit is bad
- 125 -- Commit should be skipped (cannot test)
The script approach is more reliable than manual marking because it is consistent and repeatable.
Step 3: When Skip Is Unavoidable
If you must skip, do it strategically. Skip commits that are truly untestable, and try to test everything else:
```bash git bisect start git bisect bad HEAD git bisect good v1.0
# At each step, try to test # Only skip if absolutely necessary git bisect skip ```
If bisect narrows it down to a range, manually test the remaining candidates:
```bash # Bisect says the bad commit is one of these 5 git log --oneline abc1234..def5678
# Manually checkout and test each git checkout abc1234 make test && echo "GOOD" || echo "BAD" ```
Step 4: Visualize the Bisect Progress
To understand where bisect is in the process:
git bisect visualize
# Opens gitk or git log showing the current bisect stateOr:
git log --oneline --graph --decorate bisect/bad bisect/goodThis shows the good and bad boundaries and the commits still under investigation.
Step 5: Reset Bisect After Completion
Always reset bisect when done:
git bisect resetThis returns you to the branch you were on before starting bisect and removes the bisect state.
Step 6: Bisect With Build Failures
A common scenario: the bug was introduced, but some commits between good and bad fail to build. You need to separate build failures from actual test failures:
```bash #!/bin/bash # bisect-test.sh - sophisticated bisect script
# Attempt to build if ! make -j4 2>/dev/null; then # Build failed - try to determine if this is before or after the bug # Check if a known-good function exists if grep -q "known_good_function" src/core.c; then # This commit is after the refactor, build failure is the bug exit 1 # Mark as bad else # This commit is before the refactor, skip it exit 125 # Skip fi fi
# Build succeeded - run the actual test ./test-bug.sh exit $? ```
This script attempts to classify build failures as either "before the refactoring" (skip) or "the bug itself" (bad), reducing unnecessary skips.
Step 7: Bisect Log for Review
Save the bisect log for later review:
git bisect log > bisect-session.logYou can replay this session later:
git bisect replay bisect-session.logThis is useful for documenting the investigation process and for sharing with team members.
Best Practices for Git Bisect
- 1.**Use
bisect run** with a reliable test script whenever possible - 2.Make the test script as specific as possible to the bug you are tracking
- 3.Only skip when truly untestable -- try to determine good/bad manually
- 4.Keep the good commit as close to the bad commit as possible to reduce the search space
- 5.Document the bisect session with
git bisect logfor future reference