Patchwork [3,of,4] filemerge: add internal merge tool to dump files forcibly

login
register
mail settings
Submitter Katsunori FUJIWARA
Date May 12, 2017, 6:42 p.m.
Message ID <f175a47c78c9a6bdc640.1494614530@speaknoevil>
Download mbox | patch
Permalink /patch/20590/
State Accepted
Headers show

Comments

Katsunori FUJIWARA - May 12, 2017, 6:42 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1494613902 -32400
#      Sat May 13 03:31:42 2017 +0900
# Node ID f175a47c78c9a6bdc640b278f9055b097cec29db
# Parent  44e2659be1bd4f1b59dbf2b5bf575c179730cd75
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.

Patch

diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -458,7 +458,11 @@  def _idump(repo, mynode, orig, fcd, fco,
     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 @@  def _idump(repo, mynode, orig, fcd, fco,
     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():
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -1760,11 +1760,18 @@  Test dynamic list of merge tools only sh
         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.
   
diff --git a/tests/test-merge-tools.t b/tests/test-merge-tools.t
--- a/tests/test-merge-tools.t
+++ b/tests/test-merge-tools.t
@@ -671,6 +671,72 @@  f.other:
   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