[PATCH] filemerge: support passing python script to custom merge-tools
tom_hindle at sil.org
tom_hindle at sil.org
Tue May 1 19:51:01 UTC 2018
# HG changeset patch
# User hindlemail <tom_hindle at sil.org>
# Date 1523988043 21600
# Tue Apr 17 12:00:43 2018 -0600
# Node ID 279036df5b14e08c09e95222b2dc61b279b5733a
# Parent 92213f6745ed6f2c50feca9a2261b6f33a9a32fa
filemerge: support passing python script to custom merge-tools
Eliminates the need to specify a python execuatable, which may not exist on
system. Additionally launching script inprocess aids portablity on systems that
can't execute python via the shell.
example usage "merge-tools.myTool.executable=python:c:\myTool.py"
diff -r 92213f6745ed -r 279036df5b14 mercurial/filemerge.py
--- a/mercurial/filemerge.py Sun Mar 04 15:29:41 2018 -0500
+++ b/mercurial/filemerge.py Tue Apr 17 12:00:43 2018 -0600
@@ -11,6 +11,7 @@
import os
import re
import shutil
+import sys
import tempfile
from .i18n import _
@@ -114,6 +115,9 @@
def _findtool(ui, tool):
if tool in internals:
return tool
+ cmd = _toolstr(ui, tool, "executable", tool)
+ if cmd.startswith('python:'):
+ return cmd
return findexternaltool(ui, tool)
def findexternaltool(ui, tool):
@@ -325,7 +329,7 @@
return filectx
def _premerge(repo, fcd, fco, fca, toolconf, files, labels=None):
- tool, toolpath, binary, symlink = toolconf
+ tool, toolpath, binary, symlink, script = toolconf
if symlink or fcd.isabsent() or fco.isabsent():
return 1
unused, unused, unused, back = files
@@ -361,7 +365,7 @@
return 1 # continue merging
def _mergecheck(repo, mynode, orig, fcd, fco, fca, toolconf):
- tool, toolpath, binary, symlink = toolconf
+ tool, toolpath, binary, symlink, script = toolconf
if symlink:
repo.ui.warn(_('warning: internal %s cannot merge symlinks '
'for %s\n') % (tool, fcd.path()))
@@ -430,7 +434,7 @@
Generic driver for _imergelocal and _imergeother
"""
assert localorother is not None
- tool, toolpath, binary, symlink = toolconf
+ tool, toolpath, binary, symlink, script = toolconf
r = simplemerge.simplemerge(repo.ui, fcd, fca, fco, label=labels,
localorother=localorother)
return True, r
@@ -510,7 +514,7 @@
'external merge tools')
def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
- tool, toolpath, binary, symlink = toolconf
+ tool, toolpath, binary, symlink, script = toolconf
if fcd.isabsent() or fco.isabsent():
repo.ui.warn(_('warning: %s cannot merge change/delete conflict '
'for %s\n') % (tool, fcd.path()))
@@ -556,7 +560,17 @@
repo.ui.status(_('running merge tool %s for file %s\n') %
(tool, fcd.path()))
repo.ui.debug('launching merge tool: %s\n' % cmd)
- r = ui.system(cmd, cwd=repo.root, environ=env, blockedtag='mergetool')
+ if not script:
+ r = ui.system(cmd, cwd=repo.root, environ=env,
+ blockedtag='mergetool')
+ else:
+ r = 0
+ try:
+ sys.argv = procutil.shellsplit(cmd)
+ execfile(procutil.shellsplit(toolpath)[0], {})
+ except Exception as err:
+ r = 1
+ repo.ui.debug('merge tool threw exception: %s\n' % err.args[0])
repo.ui.debug('merge tool returned: %d\n' % r)
return True, r, False
@@ -751,9 +765,13 @@
symlink = 'l' in fcd.flags() + fco.flags()
changedelete = fcd.isabsent() or fco.isabsent()
tool, toolpath = _picktool(repo, ui, fd, binary, symlink, changedelete)
+ script = False
if tool in internals and tool.startswith('internal:'):
# normalize to new-style names (':merge' etc)
tool = tool[len('internal'):]
+ if toolpath and procutil.shellsplit(toolpath)[0].startswith('python:'):
+ toolpath = toolpath.replace('python:', '')
+ script = True
ui.debug("picked tool '%s' for %s (binary %s symlink %s changedelete %s)\n"
% (tool, fd, pycompat.bytestr(binary), pycompat.bytestr(symlink),
pycompat.bytestr(changedelete)))
@@ -774,7 +792,7 @@
precheck = None
isexternal = True
- toolconf = tool, toolpath, binary, symlink
+ toolconf = tool, toolpath, binary, symlink, script
if mergetype == nomerge:
r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf, labels)
More information about the Mercurial-devel
mailing list