[PATCH 1 of 2] filemerge: add support for multiple merge tool versions (RFC)
Mathias De Maré
mathias.demare at gmail.com
Wed Dec 16 07:07:03 UTC 2015
# HG changeset patch
# User Mathias De Maré <mathias.demare at gmail.com>
# Date 1450249051 -3600
# Wed Dec 16 07:57:31 2015 +0100
# Node ID 958659a81ec2cea8037e4e8ba1bf9841c0272f88
# Parent 7e8a883da1711008262150bb6f64131812de3e0b
filemerge: add support for multiple merge tool versions (RFC)
Previously, it was only possible to specify a single set of
mergetool arguments.
In case of new mergetool features, it was not possible to enable
these due to compatibility concerns.
This patch allows specifying a different 'minimum version'
for a specific set of arguments.
diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -12,6 +12,8 @@
import re
import tempfile
+from StringIO import StringIO
+
from .i18n import _
from .node import nullid, short
@@ -452,6 +454,49 @@
repo.wwrite(fd + ".base", fca.data(), fca.flags())
return False, 1, False
+def _findversionedargs(repo, ui, tool, toolpath, env):
+ args = _toolstr(ui, tool, "args", '$local $base $other')
+
+ versionlist = _toollist(ui, tool, "versions")
+ if not versionlist:
+ return args
+
+ check = _toolstr(ui, tool, "versioncheckargs", "--version")
+
+ output = StringIO()
+ r = util.system(toolpath + ' ' + check, environ=env, out=output)
+ repo.ui.debug('merge tool version returned: %d\n' % r)
+ output.seek(0)
+ versionoutput = output.read()
+ repo.ui.debug('merge tool version: %s\n' % versionoutput)
+
+ regex = _toolstr(ui, tool, "versionregex")
+ if not regex:
+ repo.ui.debug('merge tool did not specify version regex, ' \
+ 'falling back to default args\n')
+ return args
+
+ repo.ui.debug('detecting merge tool version with regex %s\n' % regex)
+
+ versionmatch = re.search(regex, versionoutput)
+ if not versionmatch:
+ repo.ui.debug('failed to find merge tool version, ' \
+ 'falling back to default args\n')
+ return args
+
+ localversion = versionmatch.group(1)
+ selectedversion = None
+ for version in versionlist: #assume ascending
+ if util.versiontuple(localversion) < version:
+ continue
+ selectedversion = version
+
+ if selectedversion:
+ repo.ui.debug('selected merge tool base version: %s\n'
+ % selectedversion)
+ args = _toolstr(ui, tool, "args." + selectedversion)
+ return args
+
def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
tool, toolpath, binary, symlink = toolconf
if fcd.isabsent() or fco.isabsent():
@@ -471,7 +516,8 @@
ui = repo.ui
- args = _toolstr(ui, tool, "args", '$local $base $other')
+ args = _findversionedargs(repo, ui, tool, toolpath, env)
+
if "$output" in args:
out, a = a, back # read input from backup, write to original
replace = {'local': a, 'base': b, 'other': c, 'output': out}
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
@@ -1130,6 +1130,51 @@
# hg resolve --list
R f
+Handling a merge tool with different version
+
+ $ cat << EOF > versionedtool
+ > if [ "\$1" = "--version" ]; then
+ > echo "\$MERGETOOLVERSION";
+ > else
+ > echo "Running with args \$@";
+ > fi
+ > EOF
+ $ beforemerge
+ [merge-tools]
+ false.whatever=
+ true.priority=1
+ true.executable=cat
+ # hg update -C 1
+
+ $ export MERGETOOLVERSION=1.2
+ $ hg merge -r 2 \
+ > --config merge-tools.true.executable='sh' \
+ > --config merge-tools.true.args='./versionedtool older-than-1.3' \
+ > --config merge-tools.true.versions='1.3' \
+ > --config merge-tools.true.args.1.3='./versionedtool 1.3-or-newer' \
+ > --config merge-tools.true.versionregex='(\d\.\d\.\d)' \
+ > --config merge-tools.true.versioncheckargs='./versionedtool --version'
+ merging f
+ Running with args older-than-1.3
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ hg up -C 1
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ export MERGETOOLVERSION=1.3.1
+ $ hg merge -r 2 \
+ > --config merge-tools.true.executable='sh' \
+ > --config merge-tools.true.args='./versionedtool older-than-1.3' \
+ > --config merge-tools.true.versions='1.3' \
+ > --config merge-tools.true.args.1.3='./versionedtool 1.3-or-newer' \
+ > --config merge-tools.true.versionregex='(\d\.\d\.\d)' \
+ > --config merge-tools.true.versioncheckargs='./versionedtool --version'
+ merging f
+ Running with args 1.3-or-newer
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ rm versionedtool
+
Issue3581: Merging a filename that needs to be quoted
(This test doesn't work on Windows filesystems even on Linux, so check
for Unix-like permission)
More information about the Mercurial-devel
mailing list