##// END OF EJS Templates
extdiff: avoid unexpected quoting arguments for external tools (issue4463)...
FUJIWARA Katsunori -
r23680:4075f2f8 default
parent child Browse files
Show More
@@ -109,7 +109,7 b' def snapshot(ui, repo, files, node, tmpr'
109 os.lstat(dest).st_mtime))
109 os.lstat(dest).st_mtime))
110 return dirname, fns_and_mtime
110 return dirname, fns_and_mtime
111
111
112 def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
112 def dodiff(ui, repo, args, pats, opts):
113 '''Do the actual diff:
113 '''Do the actual diff:
114
114
115 - copy to a temp structure if diffing 2 internal revisions
115 - copy to a temp structure if diffing 2 internal revisions
@@ -120,7 +120,6 b' def dodiff(ui, repo, diffcmd, diffopts, '
120
120
121 revs = opts.get('rev')
121 revs = opts.get('rev')
122 change = opts.get('change')
122 change = opts.get('change')
123 args = ' '.join(map(util.shellquote, diffopts))
124 do3way = '$parent2' in args
123 do3way = '$parent2' in args
125
124
126 if revs and change:
125 if revs and change:
@@ -222,8 +221,7 b' def dodiff(ui, repo, diffcmd, diffopts, '
222 regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)'
221 regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)'
223 if not do3way and not re.search(regex, args):
222 if not do3way and not re.search(regex, args):
224 args += ' $parent1 $child'
223 args += ' $parent1 $child'
225 args = re.sub(regex, quote, args)
224 cmdline = re.sub(regex, quote, args)
226 cmdline = util.shellquote(diffcmd) + ' ' + args
227
225
228 ui.debug('running %r in %s\n' % (cmdline, tmproot))
226 ui.debug('running %r in %s\n' % (cmdline, tmproot))
229 ui.system(cmdline, cwd=tmproot)
227 ui.system(cmdline, cwd=tmproot)
@@ -271,7 +269,8 b' def extdiff(ui, repo, *pats, **opts):'
271 if not program:
269 if not program:
272 program = 'diff'
270 program = 'diff'
273 option = option or ['-Npru']
271 option = option or ['-Npru']
274 return dodiff(ui, repo, program, option, pats, opts)
272 cmdline = ' '.join(map(util.shellquote, [program] + option))
273 return dodiff(ui, repo, cmdline, pats, opts)
275
274
276 def uisetup(ui):
275 def uisetup(ui):
277 for cmd, path in ui.configitems('extdiff'):
276 for cmd, path in ui.configitems('extdiff'):
@@ -281,29 +280,37 b' def uisetup(ui):'
281 path = util.findexe(cmd)
280 path = util.findexe(cmd)
282 if path is None:
281 if path is None:
283 path = filemerge.findexternaltool(ui, cmd) or cmd
282 path = filemerge.findexternaltool(ui, cmd) or cmd
284 diffopts = shlex.split(ui.config('extdiff', 'opts.' + cmd, ''))
283 diffopts = ui.config('extdiff', 'opts.' + cmd, '')
284 cmdline = util.shellquote(path)
285 if diffopts:
286 cmdline += ' ' + diffopts
285 elif cmd.startswith('opts.'):
287 elif cmd.startswith('opts.'):
286 continue
288 continue
287 else:
289 else:
288 # command = path opts
289 if path:
290 if path:
290 diffopts = shlex.split(path)
291 # case "cmd = path opts"
291 path = diffopts.pop(0)
292 cmdline = path
293 diffopts = len(shlex.split(cmdline)) > 1
292 else:
294 else:
293 path, diffopts = util.findexe(cmd), []
295 # case "cmd ="
296 path = util.findexe(cmd)
294 if path is None:
297 if path is None:
295 path = filemerge.findexternaltool(ui, cmd) or cmd
298 path = filemerge.findexternaltool(ui, cmd) or cmd
299 cmdline = util.shellquote(path)
300 diffopts = False
296 # look for diff arguments in [diff-tools] then [merge-tools]
301 # look for diff arguments in [diff-tools] then [merge-tools]
297 if diffopts == []:
302 if not diffopts:
298 args = ui.config('diff-tools', cmd+'.diffargs') or \
303 args = ui.config('diff-tools', cmd+'.diffargs') or \
299 ui.config('merge-tools', cmd+'.diffargs')
304 ui.config('merge-tools', cmd+'.diffargs')
300 if args:
305 if args:
301 diffopts = shlex.split(args)
306 cmdline += ' ' + args
302 def save(cmd, path, diffopts):
307 def save(cmdline):
303 '''use closure to save diff command to use'''
308 '''use closure to save diff command to use'''
304 def mydiff(ui, repo, *pats, **opts):
309 def mydiff(ui, repo, *pats, **opts):
305 return dodiff(ui, repo, path, diffopts + opts['option'],
310 options = ' '.join(map(util.shellquote, opts['option']))
306 pats, opts)
311 if options:
312 options = ' ' + options
313 return dodiff(ui, repo, cmdline + options, pats, opts)
307 doc = _('''\
314 doc = _('''\
308 use %(path)s to diff repository (or selected files)
315 use %(path)s to diff repository (or selected files)
309
316
@@ -325,6 +332,6 b' use %(path)s to diff repository (or sele'
325 # right encoding) prevents that.
332 # right encoding) prevents that.
326 mydiff.__doc__ = doc.decode(encoding.encoding)
333 mydiff.__doc__ = doc.decode(encoding.encoding)
327 return mydiff
334 return mydiff
328 cmdtable[cmd] = (save(cmd, path, diffopts),
335 cmdtable[cmd] = (save(cmdline),
329 cmdtable['extdiff'][1][1:],
336 cmdtable['extdiff'][1][1:],
330 _('hg %s [OPTION]... [FILE]...') % cmd)
337 _('hg %s [OPTION]... [FILE]...') % cmd)
@@ -94,6 +94,72 b' Check diff are made from the first paren'
94 diffing */extdiff.*/a.2a13a4d2da36/a a.46c0e4daeb72/a (glob)
94 diffing */extdiff.*/a.2a13a4d2da36/a a.46c0e4daeb72/a (glob)
95 diff-like tools yield a non-zero exit code
95 diff-like tools yield a non-zero exit code
96
96
97 issue4463: usage of command line configuration without additional quoting
98
99 $ cat <<EOF >> $HGRCPATH
100 > [extdiff]
101 > cmd.4463a = echo
102 > opts.4463a = a-naked 'single quoted' "double quoted"
103 > 4463b = echo b-naked 'single quoted' "double quoted"
104 > echo =
105 > EOF
106 $ hg update -q -C 0
107 $ echo a >> a
108 #if windows
109 $ hg --debug 4463a | grep '^running'
110 running '"echo" a-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
111 $ hg --debug 4463b | grep '^running'
112 running 'echo b-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
113 $ hg --debug echo | grep '^running'
114 running '"*echo*" "*\\a" "*\\a"' in */extdiff.* (glob)
115 #else
116 $ hg --debug 4463a | grep '^running'
117 running '\'echo\' a-naked \'single quoted\' "double quoted" \'*/a\' \'$TESTTMP/a/a\'' in */extdiff.* (glob)
118 $ hg --debug 4463b | grep '^running'
119 running 'echo b-naked \'single quoted\' "double quoted" \'*/a\' \'$TESTTMP/a/a\'' in */extdiff.* (glob)
120 $ hg --debug echo | grep '^running'
121 running "'*echo*' '*/a' '$TESTTMP/a/a'" in */extdiff.* (glob)
122 #endif
123
124 (getting options from other than extdiff section)
125
126 $ cat <<EOF >> $HGRCPATH
127 > [extdiff]
128 > # using diff-tools diffargs
129 > 4463b2 = echo
130 > # using merge-tools diffargs
131 > 4463b3 = echo
132 > # no diffargs
133 > 4463b4 = echo
134 > [diff-tools]
135 > 4463b2.diffargs = b2-naked 'single quoted' "double quoted"
136 > [merge-tools]
137 > 4463b3.diffargs = b3-naked 'single quoted' "double quoted"
138 > EOF
139 #if windows
140 $ hg --debug 4463b2 | grep '^running'
141 running 'echo b2-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
142 $ hg --debug 4463b3 | grep '^running'
143 running 'echo b3-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
144 $ hg --debug 4463b4 | grep '^running'
145 running 'echo "*\\a" "*\\a"' in */extdiff.* (glob)
146 $ hg --debug 4463b4 --option 'being quoted' | grep '^running'
147 running 'echo "being quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
148 $ hg --debug extdiff -p echo --option 'being quoted' | grep '^running'
149 running '"echo" "being quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
150 #else
151 $ hg --debug 4463b2 | grep '^running'
152 running 'echo b2-naked \'single quoted\' "double quoted" \'*/a\' \'$TESTTMP/a/a\'' in */extdiff.* (glob)
153 $ hg --debug 4463b3 | grep '^running'
154 running 'echo b3-naked \'single quoted\' "double quoted" \'*/a\' \'$TESTTMP/a/a\'' in */extdiff.* (glob)
155 $ hg --debug 4463b4 | grep '^running'
156 running "echo '*/a' '$TESTTMP/a/a'" in */extdiff.* (glob)
157 $ hg --debug 4463b4 --option 'being quoted' | grep '^running'
158 running "echo 'being quoted' '*/a' '$TESTTMP/a/a'" in */extdiff.* (glob)
159 $ hg --debug extdiff -p echo --option 'being quoted' | grep '^running'
160 running "'echo' 'being quoted' '*/a' '$TESTTMP/a/a'" in */extdiff.* (glob)
161 #endif
162
97 #if execbit
163 #if execbit
98
164
99 Test extdiff of multiple files in tmp dir:
165 Test extdiff of multiple files in tmp dir:
@@ -207,7 +273,7 b' Fallback to merge-tools.tool.executable|'
207 making snapshot of 2 files from working directory
273 making snapshot of 2 files from working directory
208 a
274 a
209 b
275 b
210 running "'$TESTTMP/a/dir/tool.sh' 'a.*' 'a'" in */extdiff.* (glob)
276 running "'$TESTTMP/a/dir/tool.sh' 'a.*' 'a'" in */extdiff.* (glob)
211 ** custom diff **
277 ** custom diff **
212 cleaning up temp directory
278 cleaning up temp directory
213 [1]
279 [1]
General Comments 0
You need to be logged in to leave comments. Login now