D2888: filemerge: use a single temp dir instead of temp files

spectral (Kyle Lippincott) phabricator at mercurial-scm.org
Mon Mar 19 14:18:53 EDT 2018


spectral updated this revision to Diff 7122.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2888?vs=7119&id=7122

REVISION DETAIL
  https://phab.mercurial-scm.org/D2888

AFFECTED FILES
  mercurial/configitems.py
  mercurial/filemerge.py
  tests/test-merge-tools.t

CHANGE DETAILS

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
@@ -1363,6 +1363,33 @@
   (branch merge, don't forget to commit)
   $ rm -f 'printargs_merge_tool'
 
+Same test with experimental.mergetempdirprefix set:
+
+  $ beforemerge
+  [merge-tools]
+  false.whatever=
+  true.priority=1
+  true.executable=cat
+  # hg update -C 1
+  $ cat <<EOF > printargs_merge_tool
+  > while test \$# -gt 0; do echo arg: \"\$1\"; shift; done
+  > EOF
+  $ hg --config experimental.mergetempdirprefix=$TESTTMP/hgmerge. \
+  >    --config merge-tools.true.executable='sh' \
+  >    --config merge-tools.true.args='./printargs_merge_tool ll:$labellocal lo: $labelother lb:$labelbase": "$base' \
+  >    --config merge-tools.true.mergemarkertemplate='tooltmpl {short(node)}' \
+  >    --config ui.mergemarkertemplate='uitmpl {rev}' \
+  >    --config ui.mergemarkers=detailed \
+  >    merge -r 2
+  merging f
+  arg: "ll:working copy"
+  arg: "lo:"
+  arg: "merge rev"
+  arg: "lb:base: $TESTTMP/hgmerge.??????/f~base" (glob)
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ rm -f 'printargs_merge_tool'
+
 Merge using a tool that supports labellocal, labelother, and labelbase, checking
 that they're quoted properly as well. This is using 'detailed' mergemarkers,
 even though ui.mergemarkers is 'basic', and using the tool's
@@ -1562,6 +1589,20 @@
   0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
+Verify naming of temporary files and that extension is preserved
+(experimental.mergetempdirprefix version):
+
+  $ hg update -q -C 1
+  $ hg mv f f.txt
+  $ hg ci -qm "f.txt"
+  $ hg update -q -C 2
+  $ hg merge -y -r tip --tool echo \
+  >    --config merge-tools.echo.args='$base $local $other $output' \
+  >    --config experimental.mergetempdirprefix=$TESTTMP/hgmerge.
+  merging f and f.txt to f.txt
+  $TESTTMP/hgmerge.??????/f~base $TESTTMP/f.txt.orig $TESTTMP/hgmerge.??????/f~other.txt $TESTTMP/f.txt (glob)
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
 Check that debugpicktool examines which merge tool is chosen for
 specified file as expected
 
diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -10,6 +10,7 @@
 import contextlib
 import os
 import re
+import shutil
 import tempfile
 
 from .i18n import _
@@ -668,12 +669,23 @@
     """Writes out `fco` and `fca` as temporary files, so an external merge
     tool may use them.
     """
+    tmproot = None
+    tmprootprefix = repo.ui.config('experimental', 'mergetempdirprefix')
+    if tmprootprefix:
+        tmproot = tempfile.mkdtemp(prefix=tmprootprefix)
+
     def temp(prefix, ctx):
         fullbase, ext = os.path.splitext(ctx.path())
-        pre = "%s~%s." % (os.path.basename(fullbase), prefix)
-        (fd, name) = tempfile.mkstemp(prefix=pre, suffix=ext)
+        pre = "%s~%s" % (os.path.basename(fullbase), prefix)
+        if tmproot:
+            name = os.path.join(tmproot, pre)
+            if ext:
+                name += ext
+            f = open(name, r"wb")
+        else:
+            (fd, name) = tempfile.mkstemp(prefix=pre + '.', suffix=ext)
+            f = os.fdopen(fd, r"wb")
         data = repo.wwritedata(ctx.path(), ctx.data())
-        f = os.fdopen(fd, r"wb")
         f.write(data)
         f.close()
         return name
@@ -683,8 +695,11 @@
     try:
         yield b, c
     finally:
-        util.unlink(b)
-        util.unlink(c)
+        if tmproot:
+            shutil.rmtree(tmproot)
+        else:
+            util.unlink(b)
+            util.unlink(c)
 
 def _filemerge(premerge, repo, wctx, mynode, orig, fcd, fco, fca, labels=None):
     """perform a 3-way merge in the working directory
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -502,6 +502,9 @@
 coreconfigitem('experimental', 'maxdeltachainspan',
     default=-1,
 )
+coreconfigitem('experimental', 'mergetempdirprefix',
+    default=None,
+)
 coreconfigitem('experimental', 'mmapindexthreshold',
     default=None,
 )



To: spectral, #hg-reviewers, yuja
Cc: mercurial-devel


More information about the Mercurial-devel mailing list