I have a repository in which two revisions (14321 and 14319) share a parent (14318) - both changesets are direct children of 14318. Nevertheless, the revision set query ancestor(14321, 14319)
does not return 14318, but instead returns a much older changeset. What's happening?
Screenshot in TortoiseHg:
Background: I encountered odd merge conflicts recently that turned out to be caused by mercurial trying to re-apply changes that had already been merged. I was able to track it down to an odd choice of merge base which caused both heads to include the same changes - but I don't understand why this happened and how I can prevent it in the future (I chose a DVCS partly to avoid these kinds of problems in the first place...)
The picture shows there are not one but two common ancestors. So, it looks like a criss-cross merge case where merge problems arise from chosing one or another common ancestor.
References:
There is a proposal for a new merge algorithm (https://www.mercurial-scm.org/wiki/ConsensusMerge). However, since Mercurial's 2.3 sprint this topic is stuck.
To reduce this kind of problem, I suggest you to estabilish a client-server topology, so that developers only merge with the official repository. Maybe rebase could help also.
A criss-cross merge is something like this:
B --- D
/ \ / \
/ \ / \
A X F
\ / \ /
\ / \ /
C --- E
In your case, it was:
B
-----------o---- } stable/production
C \ \ F
------o------o---\------o } default
\ D \ /
-----------o--- } feature
E
A = ?
B = 14318
C = 14294
D = 14319
E = 14321
F = ?
To produce F
, there are two possible circuits: B-D-E-F
and C-D-E-F
. Mercurial has chosen the latter.
You could have avoided the criss-cross if you haven't merged production and feature branches. The hotfix could have been propagated to the feature branch via the default branch. The log would be:
B
-----------o } stable/production
C \ F
------o------o------o } default
\ D \ /
-------o--- } feature
E