[PATCH 1 of 2] filemerge: add $revbase and $revother substitutions in merge tool arguments
Adrian Buehlmann
adrian at cadifra.com
Fri Jul 13 06:41:52 CDT 2012
On 2012-07-12 22:48, Vitaliy Filippov wrote:
> # HG changeset patch
> # User Vitaliy Filippov <vitalif at yourcmc.ru>
> # Date 1342116873 -14400
> # Node ID 2422f58a70bcfbf20ec42edf9e1353fdc3f2bfc2
> # Parent 3ac9592b7ab432e1470ec97d19c9b7c58c3fda86
> filemerge: add $revbase and $revother substitutions in merge tool arguments
>
> Usage example:
>
> [merge-tools]
> filemerge.executable = /usr/bin/merge
> filemerge.args = -L local -L "base (rev $revbase)" -L "other (rev $revother)" -A $local $base $other
>
> diff -r 3ac9592b7ab4 -r 2422f58a70bc mercurial/filemerge.py
> --- a/mercurial/filemerge.py Thu Jul 12 14:20:34 2012 -0500
> +++ b/mercurial/filemerge.py Thu Jul 12 22:14:33 2012 +0400
> @@ -253,7 +253,7 @@
> args = _toolstr(ui, tool, "args", '$local $base $other')
> if "$output" in args:
> out, a = a, back # read input from backup, write to original
> - replace = dict(local=a, base=b, other=c, output=out)
> + replace = dict(local=a, base=b, other=c, output=out, revbase=fca.rev(), revother=fco.rev())
> args = util.interpolate(r'\$', replace, args,
> lambda s: '"%s"' % util.localpath(s))
> r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env,
This produces a traceback on Windows:
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)]
** Mercurial Distributed SCM (version 2.2.3+27-e12eae2701c5)
** Extensions loaded:
Traceback (most recent call last):
File "C:/Users/adi/hgrepos/hg-main/hg", line 38, in <module>
mercurial.dispatch.run()
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 28, in run
sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 65, in dispatch
return _runcatch(req)
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 88, in _runcatch
return _dispatch(req)
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 739, in _dispatch
cmdpats, cmdoptions)
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 513, in runcommand
ret = _runcommand(ui, options, cmd, d)
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 829, in _runcommand
return checkargs()
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 800, in checkargs
return cmdfunc()
File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 736, in <lambda>
d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
File "C:\Users\adi\hgrepos\hg-main\mercurial\util.py", line 475, in check
return func(*args, **kwargs)
File "C:\Users\adi\hgrepos\hg-main\mercurial\commands.py", line 4258, in merge
return hg.merge(repo, node, force=opts.get('force'))
File "C:\Users\adi\hgrepos\hg-main\mercurial\hg.py", line 435, in merge
stats = mergemod.update(repo, node, True, force, False)
File "C:\Users\adi\hgrepos\hg-main\mercurial\merge.py", line 610, in update
stats = applyupdates(repo, action, wc, p2, pa, overwrite)
File "C:\Users\adi\hgrepos\hg-main\mercurial\merge.py", line 373, in applyupdates
r = ms.resolve(fd, wctx, mctx)
File "C:\Users\adi\hgrepos\hg-main\mercurial\merge.py", line 76, in resolve
r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
File "C:\Users\adi\hgrepos\hg-main\mercurial\filemerge.py", line 322, in filemerge
(a, b, c, back))
File "C:\Users\adi\hgrepos\hg-main\mercurial\filemerge.py", line 258, in _xmerge
lambda s: '"%s"' % util.localpath(s))
File "C:\Users\adi\hgrepos\hg-main\mercurial\util.py", line 1447, in interpolate
return r.sub(lambda x: fn(mapping[x.group()[1:]]), s)
File "C:\Users\adi\hgrepos\hg-main\mercurial\util.py", line 1447, in <lambda>
return r.sub(lambda x: fn(mapping[x.group()[1:]]), s)
File "C:\Users\adi\hgrepos\hg-main\mercurial\filemerge.py", line 258, in <lambda>
lambda s: '"%s"' % util.localpath(s))
File "C:\Users\adi\hgrepos\hg-main\mercurial\windows.py", line 128, in localpath
return path.replace('/', '\\')
AttributeError: 'int' object has no attribute 'replace'
fca.rev() and fco.rev() return int objects, but the line
args = util.interpolate(r'\$', replace, args,
lambda s: '"%s"' % util.localpath(s))
then calls util.localpath(s) on those int's, which expects an str object.
On posix platforms (e.g. Linux), util.localpath does nothing (see posix.py, line 152),
but on Windows (see windows.py, line 127), it is defined as:
def localpath(path):
return path.replace('/', '\\')
So the current code expects those arguments to be paths.
I think the idea of your patch is good and I assume it worked on your platfrom.
What we probably need to do, is to think about whether we really should still
assume those arguments to be paths.
Since Windows can deal well with slashes as separator in paths, I think that
localpath() call in filemerge.py can be removed.
This should be done with a separate, initial patch.
Next problem is, that I think we should still make sure *strings* are put into
the dict. But with
replace = dict(local=a, base=b, other=c, output=out, revbase=fca.rev(), revother=fco.rev())
you put int's into the dict.
Another question is, if it is really a good idea to put revision numbers in there.
Perhaps this should use
short(fca.node())
instead of
fca.rev()
(same for fco)
While we're at it, that line violates the style rules for python sources of
Mercurial, which is detected by the check-code test of the testsuite:
$ PATH="/mingw/bin:/bin:/c/python:/c/python/scripts" python run-tests.py --local test-check*
--- C:\Users\adi\hgrepos\hg-main\tests\test-check-code-hg.t
+++ C:\Users\adi\hgrepos\hg-main\tests\test-check-code-hg.t.err
@@ -6,6 +6,10 @@
> exit 80
> fi
$ hg manifest | xargs "$check_code" || echo 'FAILURE IS NOT AN OPTION!!!'
+ mercurial/filemerge.py:256:
+ > replace = dict(local=a, base=b, other=c, output=out, revbase=fca.rev(), revother=fco.rev())
+ line too long
+ FAILURE IS NOT AN OPTION!!!
$ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 || true
hgext/convert/cvsps.py:0:
@@ -159,6 +163,9 @@
mercurial/commands.py:0:
> ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
warning: unwrapped ui message
+ mercurial/filemerge.py:0:
+ > replace = dict(local=a, base=b, other=c, output=out, revbase=fca.rev(), revother=fco.rev())
+ line too long
tests/autodiff.py:0:
> ui.write('data lost for: %s\n' % fn)
warning: unwrapped ui message
ERROR: C:\Users\adi\hgrepos\hg-main\tests\test-check-code-hg.t output changed
!..
Failed test-check-code-hg.t: output changed
# Ran 3 tests, 0 skipped, 1 failed.
So this proves that you didn't run the testsuite for this patch.
So you missed at least the item "test suite has been updated and runs cleanly"
as noted on
http://mercurial.selenic.com/wiki/ContributingChanges#Submission_checklist
Running the testsuite on Linux should be as simple as:
$ cd tests
$ python run-tests.py
More information about the Mercurial-devel
mailing list