We permit the caller of merge operations to supply labels for the merge
parts ("local", "other", and optionally "base"). These labels are used in
conflict markers to reduce confusion; however, the labels were not
persistent, so 'hg resolve' would lose the labels.
Store the labels in the mergestate.
During a merge, each file has a current commitnode+filenode, an other
commitnode+filenode, and an ancestor commitnode+filenode. The ancestor
commitnode is not stored though, and we rely on the ability for the filectx() to
look up the commitnode by using the filenode's linkrev. In alternative backends
(like remotefilelog), linkrevs may have restriction that prevent arbitrary
linkrev look up given a filenode.
This patch accounts for that by storing the ancestor commitnode in
the merge state so that it is available later at resolve time.
This results in some test changes because the ancestor commitnode we're using at
resolve time changes slightly. Before, we used the linkrev commit, which is the
earliest commit that introduced that particular filenode (which may not be the
latest common ancestor of the commits being merged). Now we use the latest
common ancestor of the merged commits as the commitnode. This is fine though,
because that commit contains the same filenode as the linkrev'd commit.
This is so much easier to read than a long string of zeroes, and we're going to
have a lot more of these nodes once change/delete conflicts are part of the
merge state.
This works around a bug in older Mercurial versions' handling of the v2 merge
state.
We also add a bunch of tests that make sure that
(1) we correctly abort when the merge state has an unsupported record type
(2) aborting the merge, rebase or histedit continues to work and clears out the
merge state.
The current output for a failed merge with conflict markers looks something like:
merging foo
warning: conflicts during merge.
merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
merging bar
warning: conflicts during merge.
merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')
We're going to change the way merges are done to perform all premerges before
all merges, so that the output above would look like:
merging foo
merging bar
warning: conflicts during merge.
merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
warning: conflicts during merge.
merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')
The 'warning: conflicts during merge' line has no context, so is pretty
confusing.
This patch will change the future output to:
merging foo
merging bar
warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
warning: conflicts while merging bar! (edit, then use 'hg resolve --mark')
The hint on how to resolve the conflicts makes this a bit unwieldy, but solving
that is tricky because we already hint that people run 'hg resolve' to retry
unresolved merges. The 'hg resolve --mark' mostly applies to conflict marker
based resolution.
Previously it was impossible to graft a commit onto it's own parent (i.e. create
a copy of the commit). This is useful when wanting to create a backup of the
commit before continuing to amend it. This patch enables that behavior.
The change to the histedit test is because histedit uses graft to apply commits.
The test in question moves a commit backwards onto an ancestor. Since the graft
logic now more explicitly supports this, it knows to simply accept the incoming
changes (since they are more recent), instead of prompting.
This broke some internal automation that was quite reasonably checking for
unresolved files as a way to determine whether a merge happened cleanly. We
still abort for resolve --mark etc.
The resolve command is only relevant when mergestate is present.
This patch will make resolve abort when no mergestate is present.
This change will let people know when they are using resolve when they
shouldn't be. This change will let people know when their use of resolve
doesn't do anything.
Previously, |hg resolve -m| would allow mergestate to be created. This
patch now forbids that. Strictly speaking, this is backwards
incompatible. The author of this patch believes creating mergestate via
resolve doesn't make much sense and this side-effect was unintended.
This is simpler than temporary file version. There some minor test
changes since commit messages are no longer modifed. There is still
some tests using --commands with a real file.
The old and fragile patching logic is replaced by smart merges (as rebase and
graft do). This should prevents some conflicts and smoother human resolution.
For this purpose the "foldchanges" function is renamed to "applychanges" and
handle a single revision only.