Hi Junio,
From: "Junio C Hamano" <gitster@xxxxxxxxx>
"Philip Oakley" <philipoakley@xxxxxxx> writes:
From: "Junio C Hamano" <gitster@xxxxxxxxx>
"Philip Oakley" <philipoakley@xxxxxxx> writes:
The commit graph. We are looking for F based on knowing J.
. A - B - C - D -- E -- F -- G - H <-first parent, --merges (C,F,H)
. \ | / \ / /
. ----Z | / /
. | | | /
. \ \ / /
. I -[J]- K - L - M <-since J, children of J
. \ /
. N - O - P
I think these two operations are fundamentally incompatible.
If I run them independently, they both find the desired INTERESTED
commit, hence the expectation that together they will still find that
commit as an intersection between the two sets.
Because the first-parent traversal is what the name says, i.e.,
forbids the positive side of revision traversal to stray into side
branches, the positive side of a traversal that begins at H will not
see M, L and K.
But it does see F the ultimately desired commit.
You are doing --merges --first-parent, right? Traversing only the
first-parent chain on the positive side, while excluding J's
ancestor by traversing the negative side without being limited to
the first-parent chain, would paint B and its ancestors as
uninteresting on the first-parent chain, so among H, G, F, E, D and
C, which are the survivors on the first-parent chain that are still
not UNINTERESTIN, the last one you would find that is a merge is F.
So I do not see any room for "But" to come in here...
The confusion is between the "As required" and "as coded" viewpoints (this
is regular dayjob problem of allegedly having 'requirement specifications').
You have rightly described the algorithm as currently implemented, while I
was was trying to state a requirement (based on a user question).
The user question was, given a commit 'J', and a future commit 'H'
(typically a branch tip such as 'master'), find those commits that are :
A) merges
B) on the first parent DAG chain of the future commit 'H'
C) children of the given commit 'J'
i.e. the points on master where the feature J (and it's children) could have
brought in some effect to master.
Each of the three conditions match one of the revision list options, but the
implemented logic does not produce the AND effect that could be expected.
Essentially it (the user's desire vs the coding implementation) is a case
where (depending on the viewpoint) we get the 'denying the antecedent'
fallacy.
Just because a commit is not --first-parent does not mean that revison
walking (in this case) should stop. The user is interested in the ancestry
path, so from that perspective the the walk should carry on through the
other parents till its reaches the TRULY_DISINTERESTED line, or reaches J.
With the current implementation one appears to need to script a search
through all the first parent merges and then prune out those that aren't
merge-base is-ancestor commits, which is what the OP ended up having to do.
I haven't had any time to look into the rev-walk code itself, but is this
something that could be coded (new option) or is the double-duty problem
with UNINTERESTING too hard baked into the code?
--
Philip