filemerge: add internal merge tool to dump files forcibly
Internal merge tool :dump implies premerge. Therefore, files aren't
dumped, if premerge runs successfully.
This undocumented behavior might confuse users, if they want to always
dump files. But just making :dump omit premerge might cause backward
compatibility issue for existing automation.
This patch adds new internal merge tool :forcedump, which works as
same as :dump, but omits premerge always.
Internal tools annotated with "nomerge" should merge "change and
delete" correctly, but _forcedump() can't. Therefore, it is annotated
with "mergeonly" to always omit premerge, even though it doesn't merge
files actually.
This patch also adds explanation about premerge to :dump, to clarify
how :dump actually works.
BTW, this patch specifies internal tools with "internal:" prefix in
newly added test scenario in test-merge-tools.t, even though this
prefix is already deprecated. This is only for similarity to other
tests in test-merge-tools.t.
--- a/mercurial/filemerge.py Sat May 13 03:28:36 2017 +0900
+++ b/mercurial/filemerge.py Sat May 13 03:31:42 2017 +0900
@@ -458,7 +458,11 @@
perform a merge manually. If the file to be merged is named
``a.txt``, these files will accordingly be named ``a.txt.local``,
``a.txt.other`` and ``a.txt.base`` and they will be placed in the
- same directory as ``a.txt``."""
+ same directory as ``a.txt``.
+
+ This implies permerge. Therefore, files aren't dumped, if premerge
+ runs successfully. Use :forcedump to forcibly write files out.
+ """
a, b, c, back = files
fd = fcd.path()
@@ -468,6 +472,15 @@
repo.wwrite(fd + ".base", fca.data(), fca.flags())
return False, 1, False
+@internaltool('forcedump', mergeonly)
+def _forcedump(repo, mynode, orig, fcd, fco, fca, toolconf, files,
+ labels=None):
+ """
+ Creates three versions of the files as same as :dump, but omits premerge.
+ """
+ return _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files,
+ labels=labels)
+
def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
tool, toolpath, binary, symlink = toolconf
if fcd.isabsent() or fco.isabsent():
--- a/tests/test-help.t Sat May 13 03:28:36 2017 +0900
+++ b/tests/test-help.t Sat May 13 03:31:42 2017 +0900
@@ -1760,11 +1760,18 @@
accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
they will be placed in the same directory as "a.txt".
+ This implies permerge. Therefore, files aren't dumped, if premerge runs
+ successfully. Use :forcedump to forcibly write files out.
+
":fail"
Rather than attempting to merge files that were modified on both
branches, it marks them as unresolved. The resolve command must be used
to resolve these conflicts.
+ ":forcedump"
+ Creates three versions of the files as same as :dump, but omits
+ premerge.
+
":local"
Uses the local 'p1()' version of files as the merged version.
--- a/tests/test-merge-tools.t Sat May 13 03:28:36 2017 +0900
+++ b/tests/test-merge-tools.t Sat May 13 03:31:42 2017 +0900
@@ -671,6 +671,72 @@
space
$ rm f.base f.local f.other
+check that internal:dump doesn't dump files if premerge runs
+successfully
+
+ $ beforemerge
+ [merge-tools]
+ false.whatever=
+ true.priority=1
+ true.executable=cat
+ # hg update -C 1
+ $ hg merge -r 3 --config ui.merge=internal:dump
+ merging f
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+
+ $ aftermerge
+ # cat f
+ revision 1
+ space
+ revision 3
+ # hg stat
+ M f
+ # hg resolve --list
+ R f
+
+check that internal:forcedump dumps files, even if local and other can
+be merged easily
+
+ $ beforemerge
+ [merge-tools]
+ false.whatever=
+ true.priority=1
+ true.executable=cat
+ # hg update -C 1
+ $ hg merge -r 3 --config ui.merge=internal:forcedump
+ merging f
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+ [1]
+ $ aftermerge
+ # cat f
+ revision 1
+ space
+ # hg stat
+ M f
+ ? f.base
+ ? f.local
+ ? f.orig
+ ? f.other
+ # hg resolve --list
+ U f
+
+ $ cat f.base
+ revision 0
+ space
+
+ $ cat f.local
+ revision 1
+ space
+
+ $ cat f.other
+ revision 0
+ space
+ revision 3
+
+ $ rm -f f.base f.local f.other
+
ui.merge specifies internal:other but is overruled by pattern for false:
$ beforemerge