I have a repository that uses a "trunk" flow with feature branches merging in and creating merge commits, and am using bisect to try find when issues were introduced. The issue identification process involves a comparison to results from a known-good commit, so I am using git bisect --first-parent (new in 2.29) to skip commits not in the "trunk" branch (identifying the merge commit that caused the issue is enough for me).
However, git bisect --first-parent is picking commits that do not have my first good commit as an ancestor, and I'm unsure how this is possible.
In the below example, commit 2 is good and 4 is bad.
a
/ \
1-2-3-4
Without --first-parent, I would expect feature branch commit a to be included in the bisection, however with --first-parent, I would expect it to skip that commit, and only test the merge commit, 3.
I've tested this on a mini-repository, and it behaves how I'd expect, however my much larger, much more complicated repository is not skipping commits that don't have first-good as an ancestor, and I'm struggling to understand why.
My commands are
# both "first-good" and "first-bad" are tags on the "trunk" branch
git bisect start --first-parent
git merge-base --is-ancestor first-good first-bad # returns TRUE
git merge-base first-good first-bad # returns first-good
git checkout first-bad
git bisect bad
git checkout first-good
git bisect good
git merge-base --is-ancestor first-good HEAD # returns FALSE - why/how?
git merge-base first-good HEAD # returns some other commit - why/how?
In git@47f0f94bc7, the behaviour described in the question is observed if the
first-goodcommit exists in the mainline only as the second parent of merge commit. I guess this is somewhat expected, given the name of the flag, but is does result in confusing behavior if you were relying on thefirst-goodcommit for a working build, because not all your bisects will contain that commit.For example:
git bisect --first-parentwill pickaas a commit to test, even though it is not an ancestor of the first known good commit,2. It appears to back-track toain this case, which is the first commit that is not an ancestor offirst-good. It does not test1, as that is an ancestor offirst-good, and can thus be assumed to be also good.In this example, the behaviour with or without the
--first-parentsflag is identical. Other branches starting from and merging back intotrunk2would continue to be skipped.While I'm fairly sure this is the "correct" behaviour, and for most use cases, the user won't notice a difference, the man page could use some detailing of this behaviour and/or warning given when the
first-goodcommit only exists as a second parent.This happen in my case because we "re-trunked" at some point, where commits were going into both branches simultaneously.