How to fix Some good revs are not ancestors of the bad rev in Git
This error occurs when Git bisect detects that the commit marked as 'good' is not an ancestor of the 'bad' commit. This typically happens when searching for a fix instead of a regression, or when good/bad commits are swapped.
Quick fix
Fixes Some good revs are not ancestors of the bad rev
git merge-base --is-ancestor <good-commit> <bad-commit>
echo $?- Verify the commit order
- Reset and swap good/bad if reversed
- Use old/new terminology for finding fixes
- Handle non-linear history with first-parent
git merge-base --is-ancestor <good-commit> <bad-commit>echo $?Some good revs are not ancestors of the bad rev
What this error means
Git bisect uses binary search to find the commit that introduced a bug. For this to work, it requires that the "good" commit (where the bug doesn't exist) must be an ancestor of the "bad" commit (where the bug exists). This reflects the assumption that a bug was introduced at some point and persisted in all subsequent commits. Git's history is stored as a Directed Acyclic Graph (DAG), where each commit points to its parent(s). When you mark a commit as "good" and another as "bad," Git expects to traverse from the bad commit backward through the history to reach the good commit. If the good commit is not reachable by following parent pointers from the bad commit, Git cannot perform the binary search. This error commonly appears in three scenarios: you've accidentally swapped which commit is good vs bad, you're trying to find when a bug was *fixed* rather than introduced (reverse bisect), or you're working with a complex non-linear history where branches were merged in unexpected ways.
Typical symptoms
- Git bisect fails immediately after marking commits as good and bad
- Error message: 'Some good revs are not ancestors of the bad rev'
- Additional message: 'git bisect cannot work properly in this case'
- Git suggests: 'Maybe you mistook good and bad revs?'
- Bisect session refuses to continue despite valid commits being specified
Common causes
- Good and bad commits are swapped - the 'bad' commit is actually older than the 'good' commit (most common)
- Attempting to find a fix commit instead of a regression - the bug exists in older commits but is fixed in newer ones
- Working on a feature branch that was rebased, causing historical commits to be unreachable from the current HEAD
- Complex merge history where the 'good' commit is on a parallel branch that was never merged into the path to 'bad'
- Using the wrong branch or commit reference, pointing to unrelated parts of the repository history
- Cherry-picked commits that exist in multiple places in the DAG with different ancestry relationships
How to fix "Some good revs are not ancestors of the bad rev"
First, confirm which commit is actually older. Check if the "good" commit is an ancestor of the "bad" commit:
git merge-base --is-ancestor <good-commit> <bad-commit>
echo $?If this returns 0, the good commit IS an ancestor of bad (correct order). If it returns 1, the commits are in the wrong order or on different branches.
You can also visualize the relationship:
git log --oneline --graph <good-commit>..<bad-commit>If you simply have the commits backwards, reset the bisect and start over with them swapped:
git bisect reset
git bisect start
git bisect bad <formerly-good-commit>
git bisect good <formerly-bad-commit>Remember: "good" means "the bug is NOT present" and "bad" means "the bug IS present." The bug should exist in the bad commit but not in the good commit.
If you're trying to find which commit *fixed* a bug (rather than introduced one), the traditional good/bad terminology is confusing. Git provides alternative terms:
git bisect reset
git bisect start --term-old=unfixed --term-new=fixed
git bisect unfixed <older-commit-with-bug>
git bisect fixed <newer-commit-without-bug>Or use the built-in old/new terms (Git 2.7+):
git bisect reset
git bisect start
git bisect old <commit-where-bug-exists>
git bisect new <commit-where-bug-is-fixed>Note: You cannot mix good/bad with old/new in the same session.
If you have a complex merge history and want to bisect only the mainline commits (skipping feature branch commits), use the --first-parent option (Git 2.29+):
git bisect reset
git bisect start --first-parent
git bisect bad HEAD
git bisect good <known-good-commit>This restricts bisect to follow only the first parent at each merge, typically the mainline branch.
If your good commit is on a different branch, find a common ancestor that both branches share:
git merge-base <good-commit> <bad-commit>Use this merge base as your starting point:
git bisect reset
git bisect start
git bisect bad <bad-commit>
git bisect good $(git merge-base <good-commit> <bad-commit>)This ensures the good commit is in the ancestry path of the bad commit.
Before starting bisect, visualize the commit graph to understand the relationship between commits:
git log --oneline --graph --all --decorate | head -50Or for a specific range:
git log --oneline --graph <good-commit>...<bad-commit>The three-dot syntax shows commits reachable from either commit but not both, helping you see if they're on divergent branches.
When automating bisect with a test script, ensure your script correctly handles the terminology you're using:
# For finding a regression (traditional)
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run ./test-script.sh
# For finding a fix (custom terms)
git bisect start --term-old=broken --term-new=fixed
git bisect broken v1.0.0
git bisect fixed HEAD
git bisect run ./test-script.shThe test script should exit with code 0 for "good/old/fixed" and non-zero for "bad/new/broken".
Advanced notes
### Understanding Git's DAG Structure
Git stores commits as a Directed Acyclic Graph (DAG). Each commit points to its parent commit(s), creating a tree-like structure that flows backward in time. The "acyclic" property means you can never follow parent pointers and return to where you started.
When bisect runs, it needs to find a path from the bad commit to the good commit by following parent pointers. If no such path exists (the good commit is not an ancestor of bad), bisect cannot function because there's no linear sequence of commits to binary search through.
### Binary Search Requirements
Git bisect works by repeatedly halving the range of suspect commits. For this to work:
1. The good commit must be reachable from the bad commit
2. The bug must be consistently reproducible
3. The bug must have been introduced once and persisted (no intermittent fixes and re-introductions)
### Handling Evil Merges
"Evil merges" are merge commits where the resolution itself introduces a bug (not present in either parent). These are tricky because:
- The bug only appears after the merge
- Neither parent commit shows the bug
If bisect points to a merge commit, you may need to do a secondary bisect within the merged branch, or manually examine the merge diff:
git show <merge-commit> --diff-filter=M### Theoretical Limitations
Research has shown that git bisect's algorithm, while efficient for linear history, can require exponentially more queries than optimal in complex DAGs. For very tangled histories, consider:
- Rebasing to linearize history before bisecting
- Using --first-parent to simplify the search space
- Manual binary search on a specific branch
### Skip Problematic Commits
If some commits cannot be tested (e.g., they don't compile), use skip:
git bisect skip
# Or skip a range
git bisect skip v2.0..v2.1Skipping too many commits reduces bisect's effectiveness but is better than marking untestable commits incorrectly.
Frequently asked questions
- What does "Some good revs are not ancestors of the bad rev" mean?
- Git bisect uses binary search to find the commit that introduced a bug. For this to work, it requires that the "good" commit (where the bug doesn't exist) must be an ancestor of the "bad" commit (where the bug exists). This reflects the assumption that a bug was introduced at some point and persisted in all subsequent commits.
- How do I fix "Some good revs are not ancestors of the bad rev"?
- This error occurs when Git bisect detects that the commit marked as 'good' is not an ancestor of the 'bad' commit. This typically happens when searching for a fix instead of a regression, or when good/bad commits are swapped.
- What causes "Some good revs are not ancestors of the bad rev"?
- Good and bad commits are swapped - the 'bad' commit is actually older than the 'good' commit (most common) Attempting to find a fix commit instead of a regression - the bug exists in older commits but is fixed in newer ones Working on a feature branch that was rebased, causing historical commits to be unreachable from the current HEAD
- Is the "Some good revs are not ancestors of the bad rev" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Git Official Documentation
- ๐
- ๐ฌ
- ๐ฌ
- ๐ฌStack Overflow: git bisect with merged commits(Stack Overflow)
- ๐ฌStack Overflow: how do i use git bisect(Stack Overflow)
- ๐
- ๐
- ๐
- ๐
- ๐