filemerge: use a single temp dir instead of temp files
This can help to remove the clutter from UIs that display just the filenames;
instead of seeing foo~local.C9ru9r.txt and foo~base.2DMV22.txt (in the /tmp
directory on most platforms), we create a single new directory and use that,
producing filenames like /tmp/hgmerge.C9ru9r/foo~local.txt.
Differential Revision: https://phab.mercurial-scm.org/D2888
--- a/mercurial/configitems.py Fri Jan 19 19:14:09 2018 -0800
+++ b/mercurial/configitems.py Fri Jan 19 19:07:58 2018 -0800
@@ -502,6 +502,9 @@
coreconfigitem('experimental', 'maxdeltachainspan',
default=-1,
)
+coreconfigitem('experimental', 'mergetempdirprefix',
+ default=None,
+)
coreconfigitem('experimental', 'mmapindexthreshold',
default=None,
)
--- a/mercurial/filemerge.py Fri Jan 19 19:14:09 2018 -0800
+++ b/mercurial/filemerge.py Fri Jan 19 19:07:58 2018 -0800
@@ -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
--- a/tests/test-merge-tools.t Fri Jan 19 19:14:09 2018 -0800
+++ b/tests/test-merge-tools.t Fri Jan 19 19:07:58 2018 -0800
@@ -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,21 @@
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