[PATCH 2 of 2 stable v2] extdiff: reintroduce backward compatibility with manual quoting of parameters

Mads Kiilerich mads at kiilerich.com
Tue Jan 27 19:28:54 CST 2015


# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1422408519 -3600
#      Wed Jan 28 02:28:39 2015 +0100
# Branch stable
# Node ID a1541df052e59b8fd57a1ee5ddce9628bf8ee87c
# Parent  fab8fbcb7a796798e39ad4ebfa441a8a4b6474d9
extdiff: reintroduce backward compatibility with manual quoting of parameters

72a89cf86fcd broke things ... and the following cleanups didn't fix all issues.
It didn't work with the diffargs shipped in mergetools.rc with explicit
quoting. Parameters would end up with being quoted twice - especially if they
really needed quoting.

To work around that, look for explicit quotes around the variables that will be
substituted with proper quoting. Also accept an additional prefix so we can
handle both
  --foo='$parent'
and
  '--foo=$parent'

It will however still fail if the user intentionally place the variable inside
a quoted string, as in
  'parent $parent is on the left'
There is currently no good way to handle that, short of knowing exactly which
quoting mechanism will be used.

diff --git a/hgext/extdiff.py b/hgext/extdiff.py
--- a/hgext/extdiff.py
+++ b/hgext/extdiff.py
@@ -212,13 +212,15 @@ def dodiff(ui, repo, cmdline, pats, opts
                    'clabel': label2, 'child': dir2,
                    'root': repo.root}
         def quote(match):
-            key = match.group()[1:]
+            pre = match.group(2)
+            key = match.group(3)
             if not do3way and key == 'parent2':
-                return ''
-            return util.shellquote(replace[key])
+                return pre
+            return pre + util.shellquote(replace[key])
 
         # Match parent2 first, so 'parent1?' will match both parent1 and parent
-        regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)'
+        regex = (r'''(['"]?)([^\s'"$]*)'''
+                 r'\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)\1')
         if not do3way and not re.search(regex, cmdline):
             cmdline += ' $parent1 $child'
         cmdline = re.sub(regex, quote, cmdline)
diff --git a/tests/test-extdiff.t b/tests/test-extdiff.t
--- a/tests/test-extdiff.t
+++ b/tests/test-extdiff.t
@@ -160,6 +160,28 @@ issue4463: usage of command line configu
   running "echo echo-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
 #endif
 
+  $ touch 'sp ace'
+  $ hg add 'sp ace'
+  $ hg ci -m 'sp ace'
+  created new head
+  $ echo > 'sp ace'
+
+Test pre-72a89cf86fcd backward compatibility with half-baked manual quoting
+
+  $ cat <<EOF >> $HGRCPATH
+  > [extdiff]
+  > odd =
+  > [merge-tools]
+  > odd.diffargs = --foo='\$clabel' '\$clabel' "--bar=\$clabel" "\$clabel"
+  > odd.executable = echo
+  > EOF
+#if windows
+TODO
+#else
+  $ hg --debug odd | grep '^running'
+  running "/bin/echo --foo='sp ace' 'sp ace' --bar='sp ace' 'sp ace'" in * (glob)
+#endif
+
 #if execbit
 
 Test extdiff of multiple files in tmp dir:


More information about the Mercurial-devel mailing list