##// END OF EJS Templates
extdiff: reintroduce backward compatibility with manual quoting of parameters...
Mads Kiilerich -
r23969:01e5b732 stable
parent child Browse files
Show More
@@ -1,337 +1,339
1 1 # extdiff.py - external diff program support for mercurial
2 2 #
3 3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 '''command to allow external programs to compare revisions
9 9
10 10 The extdiff Mercurial extension allows you to use external programs
11 11 to compare revisions, or revision with working directory. The external
12 12 diff programs are called with a configurable set of options and two
13 13 non-option arguments: paths to directories containing snapshots of
14 14 files to compare.
15 15
16 16 The extdiff extension also allows you to configure new diff commands, so
17 17 you do not need to type :hg:`extdiff -p kdiff3` always. ::
18 18
19 19 [extdiff]
20 20 # add new command that runs GNU diff(1) in 'context diff' mode
21 21 cdiff = gdiff -Nprc5
22 22 ## or the old way:
23 23 #cmd.cdiff = gdiff
24 24 #opts.cdiff = -Nprc5
25 25
26 26 # add new command called meld, runs meld (no need to name twice). If
27 27 # the meld executable is not available, the meld tool in [merge-tools]
28 28 # will be used, if available
29 29 meld =
30 30
31 31 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
32 32 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
33 33 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
34 34 # your .vimrc
35 35 vimdiff = gvim -f "+next" \\
36 36 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
37 37
38 38 Tool arguments can include variables that are expanded at runtime::
39 39
40 40 $parent1, $plabel1 - filename, descriptive label of first parent
41 41 $child, $clabel - filename, descriptive label of child revision
42 42 $parent2, $plabel2 - filename, descriptive label of second parent
43 43 $root - repository root
44 44 $parent is an alias for $parent1.
45 45
46 46 The extdiff extension will look in your [diff-tools] and [merge-tools]
47 47 sections for diff tool arguments, when none are specified in [extdiff].
48 48
49 49 ::
50 50
51 51 [extdiff]
52 52 kdiff3 =
53 53
54 54 [diff-tools]
55 55 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
56 56
57 57 You can use -I/-X and list of file or directory names like normal
58 58 :hg:`diff` command. The extdiff extension makes snapshots of only
59 59 needed files, so running the external diff program will actually be
60 60 pretty fast (at least faster than having to compare the entire tree).
61 61 '''
62 62
63 63 from mercurial.i18n import _
64 64 from mercurial.node import short, nullid
65 65 from mercurial import cmdutil, scmutil, util, commands, encoding, filemerge
66 66 import os, shlex, shutil, tempfile, re
67 67
68 68 cmdtable = {}
69 69 command = cmdutil.command(cmdtable)
70 70 testedwith = 'internal'
71 71
72 72 def snapshot(ui, repo, files, node, tmproot):
73 73 '''snapshot files as of some revision
74 74 if not using snapshot, -I/-X does not work and recursive diff
75 75 in tools like kdiff3 and meld displays too many files.'''
76 76 dirname = os.path.basename(repo.root)
77 77 if dirname == "":
78 78 dirname = "root"
79 79 if node is not None:
80 80 dirname = '%s.%s' % (dirname, short(node))
81 81 base = os.path.join(tmproot, dirname)
82 82 os.mkdir(base)
83 83 if node is not None:
84 84 ui.note(_('making snapshot of %d files from rev %s\n') %
85 85 (len(files), short(node)))
86 86 else:
87 87 ui.note(_('making snapshot of %d files from working directory\n') %
88 88 (len(files)))
89 89 wopener = scmutil.opener(base)
90 90 fns_and_mtime = []
91 91 ctx = repo[node]
92 92 for fn in sorted(files):
93 93 wfn = util.pconvert(fn)
94 94 if wfn not in ctx:
95 95 # File doesn't exist; could be a bogus modify
96 96 continue
97 97 ui.note(' %s\n' % wfn)
98 98 dest = os.path.join(base, wfn)
99 99 fctx = ctx[wfn]
100 100 data = repo.wwritedata(wfn, fctx.data())
101 101 if 'l' in fctx.flags():
102 102 wopener.symlink(data, wfn)
103 103 else:
104 104 wopener.write(wfn, data)
105 105 if 'x' in fctx.flags():
106 106 util.setflags(dest, False, True)
107 107 if node is None:
108 108 fns_and_mtime.append((dest, repo.wjoin(fn),
109 109 os.lstat(dest).st_mtime))
110 110 return dirname, fns_and_mtime
111 111
112 112 def dodiff(ui, repo, cmdline, pats, opts):
113 113 '''Do the actual diff:
114 114
115 115 - copy to a temp structure if diffing 2 internal revisions
116 116 - copy to a temp structure if diffing working revision with
117 117 another one and more than 1 file is changed
118 118 - just invoke the diff for a single file in the working dir
119 119 '''
120 120
121 121 revs = opts.get('rev')
122 122 change = opts.get('change')
123 123 do3way = '$parent2' in cmdline
124 124
125 125 if revs and change:
126 126 msg = _('cannot specify --rev and --change at the same time')
127 127 raise util.Abort(msg)
128 128 elif change:
129 129 node2 = scmutil.revsingle(repo, change, None).node()
130 130 node1a, node1b = repo.changelog.parents(node2)
131 131 else:
132 132 node1a, node2 = scmutil.revpair(repo, revs)
133 133 if not revs:
134 134 node1b = repo.dirstate.p2()
135 135 else:
136 136 node1b = nullid
137 137
138 138 # Disable 3-way merge if there is only one parent
139 139 if do3way:
140 140 if node1b == nullid:
141 141 do3way = False
142 142
143 143 matcher = scmutil.match(repo[node2], pats, opts)
144 144 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
145 145 if do3way:
146 146 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
147 147 else:
148 148 mod_b, add_b, rem_b = set(), set(), set()
149 149 modadd = mod_a | add_a | mod_b | add_b
150 150 common = modadd | rem_a | rem_b
151 151 if not common:
152 152 return 0
153 153
154 154 tmproot = tempfile.mkdtemp(prefix='extdiff.')
155 155 try:
156 156 # Always make a copy of node1a (and node1b, if applicable)
157 157 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
158 158 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
159 159 rev1a = '@%d' % repo[node1a].rev()
160 160 if do3way:
161 161 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
162 162 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
163 163 rev1b = '@%d' % repo[node1b].rev()
164 164 else:
165 165 dir1b = None
166 166 rev1b = ''
167 167
168 168 fns_and_mtime = []
169 169
170 170 # If node2 in not the wc or there is >1 change, copy it
171 171 dir2root = ''
172 172 rev2 = ''
173 173 if node2:
174 174 dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
175 175 rev2 = '@%d' % repo[node2].rev()
176 176 elif len(common) > 1:
177 177 #we only actually need to get the files to copy back to
178 178 #the working dir in this case (because the other cases
179 179 #are: diffing 2 revisions or single file -- in which case
180 180 #the file is already directly passed to the diff tool).
181 181 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot)
182 182 else:
183 183 # This lets the diff tool open the changed file directly
184 184 dir2 = ''
185 185 dir2root = repo.root
186 186
187 187 label1a = rev1a
188 188 label1b = rev1b
189 189 label2 = rev2
190 190
191 191 # If only one change, diff the files instead of the directories
192 192 # Handle bogus modifies correctly by checking if the files exist
193 193 if len(common) == 1:
194 194 common_file = util.localpath(common.pop())
195 195 dir1a = os.path.join(tmproot, dir1a, common_file)
196 196 label1a = common_file + rev1a
197 197 if not os.path.isfile(dir1a):
198 198 dir1a = os.devnull
199 199 if do3way:
200 200 dir1b = os.path.join(tmproot, dir1b, common_file)
201 201 label1b = common_file + rev1b
202 202 if not os.path.isfile(dir1b):
203 203 dir1b = os.devnull
204 204 dir2 = os.path.join(dir2root, dir2, common_file)
205 205 label2 = common_file + rev2
206 206
207 207 # Function to quote file/dir names in the argument string.
208 208 # When not operating in 3-way mode, an empty string is
209 209 # returned for parent2
210 210 replace = {'parent': dir1a, 'parent1': dir1a, 'parent2': dir1b,
211 211 'plabel1': label1a, 'plabel2': label1b,
212 212 'clabel': label2, 'child': dir2,
213 213 'root': repo.root}
214 214 def quote(match):
215 key = match.group()[1:]
215 pre = match.group(2)
216 key = match.group(3)
216 217 if not do3way and key == 'parent2':
217 return ''
218 return util.shellquote(replace[key])
218 return pre
219 return pre + util.shellquote(replace[key])
219 220
220 221 # Match parent2 first, so 'parent1?' will match both parent1 and parent
221 regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)'
222 regex = (r'''(['"]?)([^\s'"$]*)'''
223 r'\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)\1')
222 224 if not do3way and not re.search(regex, cmdline):
223 225 cmdline += ' $parent1 $child'
224 226 cmdline = re.sub(regex, quote, cmdline)
225 227
226 228 ui.debug('running %r in %s\n' % (cmdline, tmproot))
227 229 ui.system(cmdline, cwd=tmproot)
228 230
229 231 for copy_fn, working_fn, mtime in fns_and_mtime:
230 232 if os.lstat(copy_fn).st_mtime != mtime:
231 233 ui.debug('file changed while diffing. '
232 234 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn))
233 235 util.copyfile(copy_fn, working_fn)
234 236
235 237 return 1
236 238 finally:
237 239 ui.note(_('cleaning up temp directory\n'))
238 240 shutil.rmtree(tmproot)
239 241
240 242 @command('extdiff',
241 243 [('p', 'program', '',
242 244 _('comparison program to run'), _('CMD')),
243 245 ('o', 'option', [],
244 246 _('pass option to comparison program'), _('OPT')),
245 247 ('r', 'rev', [], _('revision'), _('REV')),
246 248 ('c', 'change', '', _('change made by revision'), _('REV')),
247 249 ] + commands.walkopts,
248 250 _('hg extdiff [OPT]... [FILE]...'),
249 251 inferrepo=True)
250 252 def extdiff(ui, repo, *pats, **opts):
251 253 '''use external program to diff repository (or selected files)
252 254
253 255 Show differences between revisions for the specified files, using
254 256 an external program. The default program used is diff, with
255 257 default options "-Npru".
256 258
257 259 To select a different program, use the -p/--program option. The
258 260 program will be passed the names of two directories to compare. To
259 261 pass additional options to the program, use -o/--option. These
260 262 will be passed before the names of the directories to compare.
261 263
262 264 When two revision arguments are given, then changes are shown
263 265 between those revisions. If only one revision is specified then
264 266 that revision is compared to the working directory, and, when no
265 267 revisions are specified, the working directory files are compared
266 268 to its parent.'''
267 269 program = opts.get('program')
268 270 option = opts.get('option')
269 271 if not program:
270 272 program = 'diff'
271 273 option = option or ['-Npru']
272 274 cmdline = ' '.join(map(util.shellquote, [program] + option))
273 275 return dodiff(ui, repo, cmdline, pats, opts)
274 276
275 277 def uisetup(ui):
276 278 for cmd, path in ui.configitems('extdiff'):
277 279 if cmd.startswith('cmd.'):
278 280 cmd = cmd[4:]
279 281 if not path:
280 282 path = util.findexe(cmd)
281 283 if path is None:
282 284 path = filemerge.findexternaltool(ui, cmd) or cmd
283 285 diffopts = ui.config('extdiff', 'opts.' + cmd, '')
284 286 cmdline = util.shellquote(path)
285 287 if diffopts:
286 288 cmdline += ' ' + diffopts
287 289 elif cmd.startswith('opts.'):
288 290 continue
289 291 else:
290 292 if path:
291 293 # case "cmd = path opts"
292 294 cmdline = path
293 295 diffopts = len(shlex.split(cmdline)) > 1
294 296 else:
295 297 # case "cmd ="
296 298 path = util.findexe(cmd)
297 299 if path is None:
298 300 path = filemerge.findexternaltool(ui, cmd) or cmd
299 301 cmdline = util.shellquote(path)
300 302 diffopts = False
301 303 # look for diff arguments in [diff-tools] then [merge-tools]
302 304 if not diffopts:
303 305 args = ui.config('diff-tools', cmd+'.diffargs') or \
304 306 ui.config('merge-tools', cmd+'.diffargs')
305 307 if args:
306 308 cmdline += ' ' + args
307 309 def save(cmdline):
308 310 '''use closure to save diff command to use'''
309 311 def mydiff(ui, repo, *pats, **opts):
310 312 options = ' '.join(map(util.shellquote, opts['option']))
311 313 if options:
312 314 options = ' ' + options
313 315 return dodiff(ui, repo, cmdline + options, pats, opts)
314 316 doc = _('''\
315 317 use %(path)s to diff repository (or selected files)
316 318
317 319 Show differences between revisions for the specified files, using
318 320 the %(path)s program.
319 321
320 322 When two revision arguments are given, then changes are shown
321 323 between those revisions. If only one revision is specified then
322 324 that revision is compared to the working directory, and, when no
323 325 revisions are specified, the working directory files are compared
324 326 to its parent.\
325 327 ''') % {'path': util.uirepr(path)}
326 328
327 329 # We must translate the docstring right away since it is
328 330 # used as a format string. The string will unfortunately
329 331 # be translated again in commands.helpcmd and this will
330 332 # fail when the docstring contains non-ASCII characters.
331 333 # Decoding the string to a Unicode string here (using the
332 334 # right encoding) prevents that.
333 335 mydiff.__doc__ = doc.decode(encoding.encoding)
334 336 return mydiff
335 337 cmdtable[cmd] = (save(cmdline),
336 338 cmdtable['extdiff'][1][1:],
337 339 _('hg %s [OPTION]... [FILE]...') % cmd)
@@ -1,302 +1,324
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "extdiff=" >> $HGRCPATH
3 3
4 4 $ hg init a
5 5 $ cd a
6 6 $ echo a > a
7 7 $ echo b > b
8 8 $ hg add
9 9 adding a
10 10 adding b
11 11
12 12 Should diff cloned directories:
13 13
14 14 $ hg extdiff -o -r $opt
15 15 Only in a: a
16 16 Only in a: b
17 17 [1]
18 18
19 19 $ cat <<EOF >> $HGRCPATH
20 20 > [extdiff]
21 21 > cmd.falabala = echo
22 22 > opts.falabala = diffing
23 23 > cmd.edspace = echo
24 24 > opts.edspace = "name <user@example.com>"
25 25 > EOF
26 26
27 27 $ hg falabala
28 28 diffing a.000000000000 a
29 29 [1]
30 30
31 31 $ hg help falabala
32 32 hg falabala [OPTION]... [FILE]...
33 33
34 34 use 'echo' to diff repository (or selected files)
35 35
36 36 Show differences between revisions for the specified files, using the
37 37 'echo' program.
38 38
39 39 When two revision arguments are given, then changes are shown between
40 40 those revisions. If only one revision is specified then that revision is
41 41 compared to the working directory, and, when no revisions are specified,
42 42 the working directory files are compared to its parent.
43 43
44 44 options ([+] can be repeated):
45 45
46 46 -o --option OPT [+] pass option to comparison program
47 47 -r --rev REV [+] revision
48 48 -c --change REV change made by revision
49 49 -I --include PATTERN [+] include names matching the given patterns
50 50 -X --exclude PATTERN [+] exclude names matching the given patterns
51 51
52 52 (some details hidden, use --verbose to show complete help)
53 53
54 54 $ hg ci -d '0 0' -mtest1
55 55
56 56 $ echo b >> a
57 57 $ hg ci -d '1 0' -mtest2
58 58
59 59 Should diff cloned files directly:
60 60
61 61 $ hg falabala -r 0:1
62 62 diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
63 63 [1]
64 64
65 65 Test diff during merge:
66 66
67 67 $ hg update -C 0
68 68 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 69 $ echo c >> c
70 70 $ hg add c
71 71 $ hg ci -m "new branch" -d '1 0'
72 72 created new head
73 73 $ hg merge 1
74 74 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
75 75 (branch merge, don't forget to commit)
76 76
77 77 Should diff cloned file against wc file:
78 78
79 79 $ hg falabala
80 80 diffing */extdiff.*/a.2a13a4d2da36/a */a/a (glob)
81 81 [1]
82 82
83 83
84 84 Test --change option:
85 85
86 86 $ hg ci -d '2 0' -mtest3
87 87 $ hg falabala -c 1
88 88 diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
89 89 [1]
90 90
91 91 Check diff are made from the first parent:
92 92
93 93 $ hg falabala -c 3 || echo "diff-like tools yield a non-zero exit code"
94 94 diffing */extdiff.*/a.2a13a4d2da36/a a.46c0e4daeb72/a (glob)
95 95 diff-like tools yield a non-zero exit code
96 96
97 97 issue4463: usage of command line configuration without additional quoting
98 98
99 99 $ cat <<EOF >> $HGRCPATH
100 100 > [extdiff]
101 101 > cmd.4463a = echo
102 102 > opts.4463a = a-naked 'single quoted' "double quoted"
103 103 > 4463b = echo b-naked 'single quoted' "double quoted"
104 104 > echo =
105 105 > EOF
106 106 $ hg update -q -C 0
107 107 $ echo a >> a
108 108 #if windows
109 109 $ hg --debug 4463a | grep '^running'
110 110 running 'echo a-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
111 111 $ hg --debug 4463b | grep '^running'
112 112 running 'echo b-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
113 113 $ hg --debug echo | grep '^running'
114 114 running '*echo* *\\a *\\a' in */extdiff.* (glob)
115 115 #else
116 116 $ hg --debug 4463a | grep '^running'
117 117 running 'echo a-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
118 118 $ hg --debug 4463b | grep '^running'
119 119 running 'echo b-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
120 120 $ hg --debug echo | grep '^running'
121 121 running '*echo */a $TESTTMP/a/a' in */extdiff.* (glob)
122 122 #endif
123 123
124 124 (getting options from other than extdiff section)
125 125
126 126 $ cat <<EOF >> $HGRCPATH
127 127 > [extdiff]
128 128 > # using diff-tools diffargs
129 129 > 4463b2 = echo
130 130 > # using merge-tools diffargs
131 131 > 4463b3 = echo
132 132 > # no diffargs
133 133 > 4463b4 = echo
134 134 > [diff-tools]
135 135 > 4463b2.diffargs = b2-naked 'single quoted' "double quoted"
136 136 > [merge-tools]
137 137 > 4463b3.diffargs = b3-naked 'single quoted' "double quoted"
138 138 > EOF
139 139 #if windows
140 140 $ hg --debug 4463b2 | grep '^running'
141 141 running 'echo b2-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
142 142 $ hg --debug 4463b3 | grep '^running'
143 143 running 'echo b3-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
144 144 $ hg --debug 4463b4 | grep '^running'
145 145 running 'echo *\\a *\\a' in */extdiff.* (glob)
146 146 $ hg --debug 4463b4 --option b4-naked --option 'being quoted' | grep '^running'
147 147 running 'echo b4-naked "being quoted" *\\a *\\a' in */extdiff.* (glob)
148 148 $ hg --debug extdiff -p echo --option echo-naked --option 'being quoted' | grep '^running'
149 149 running 'echo echo-naked "being quoted" *\\a *\\a' in */extdiff.* (glob)
150 150 #else
151 151 $ hg --debug 4463b2 | grep '^running'
152 152 running 'echo b2-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
153 153 $ hg --debug 4463b3 | grep '^running'
154 154 running 'echo b3-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
155 155 $ hg --debug 4463b4 | grep '^running'
156 156 running 'echo */a $TESTTMP/a/a' in */extdiff.* (glob)
157 157 $ hg --debug 4463b4 --option b4-naked --option 'being quoted' | grep '^running'
158 158 running "echo b4-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
159 159 $ hg --debug extdiff -p echo --option echo-naked --option 'being quoted' | grep '^running'
160 160 running "echo echo-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
161 161 #endif
162 162
163 $ touch 'sp ace'
164 $ hg add 'sp ace'
165 $ hg ci -m 'sp ace'
166 created new head
167 $ echo > 'sp ace'
168
169 Test pre-72a89cf86fcd backward compatibility with half-baked manual quoting
170
171 $ cat <<EOF >> $HGRCPATH
172 > [extdiff]
173 > odd =
174 > [merge-tools]
175 > odd.diffargs = --foo='\$clabel' '\$clabel' "--bar=\$clabel" "\$clabel"
176 > odd.executable = echo
177 > EOF
178 #if windows
179 TODO
180 #else
181 $ hg --debug odd | grep '^running'
182 running "/bin/echo --foo='sp ace' 'sp ace' --bar='sp ace' 'sp ace'" in * (glob)
183 #endif
184
163 185 #if execbit
164 186
165 187 Test extdiff of multiple files in tmp dir:
166 188
167 189 $ hg update -C 0 > /dev/null
168 190 $ echo changed > a
169 191 $ echo changed > b
170 192 $ chmod +x b
171 193
172 194 Diff in working directory, before:
173 195
174 196 $ hg diff --git
175 197 diff --git a/a b/a
176 198 --- a/a
177 199 +++ b/a
178 200 @@ -1,1 +1,1 @@
179 201 -a
180 202 +changed
181 203 diff --git a/b b/b
182 204 old mode 100644
183 205 new mode 100755
184 206 --- a/b
185 207 +++ b/b
186 208 @@ -1,1 +1,1 @@
187 209 -b
188 210 +changed
189 211
190 212
191 213 Edit with extdiff -p:
192 214
193 215 Prepare custom diff/edit tool:
194 216
195 217 $ cat > 'diff tool.py' << EOT
196 218 > #!/usr/bin/env python
197 219 > import time
198 220 > time.sleep(1) # avoid unchanged-timestamp problems
199 221 > file('a/a', 'ab').write('edited\n')
200 222 > file('a/b', 'ab').write('edited\n')
201 223 > EOT
202 224
203 225 $ chmod +x 'diff tool.py'
204 226
205 227 will change to /tmp/extdiff.TMP and populate directories a.TMP and a
206 228 and start tool
207 229
208 230 $ hg extdiff -p "`pwd`/diff tool.py"
209 231 [1]
210 232
211 233 Diff in working directory, after:
212 234
213 235 $ hg diff --git
214 236 diff --git a/a b/a
215 237 --- a/a
216 238 +++ b/a
217 239 @@ -1,1 +1,2 @@
218 240 -a
219 241 +changed
220 242 +edited
221 243 diff --git a/b b/b
222 244 old mode 100644
223 245 new mode 100755
224 246 --- a/b
225 247 +++ b/b
226 248 @@ -1,1 +1,2 @@
227 249 -b
228 250 +changed
229 251 +edited
230 252
231 253 Test extdiff with --option:
232 254
233 255 $ hg extdiff -p echo -o this -c 1
234 256 this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
235 257 [1]
236 258
237 259 $ hg falabala -o this -c 1
238 260 diffing this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
239 261 [1]
240 262
241 263 Test extdiff's handling of options with spaces in them:
242 264
243 265 $ hg edspace -c 1
244 266 name <user@example.com> */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
245 267 [1]
246 268
247 269 $ hg extdiff -p echo -o "name <user@example.com>" -c 1
248 270 name <user@example.com> */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
249 271 [1]
250 272
251 273 Test with revsets:
252 274
253 275 $ hg extdif -p echo -c "rev(1)"
254 276 */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
255 277 [1]
256 278
257 279 $ hg extdif -p echo -r "0::1"
258 280 */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
259 281 [1]
260 282
261 283 Fallback to merge-tools.tool.executable|regkey
262 284 $ mkdir dir
263 285 $ cat > 'dir/tool.sh' << EOF
264 286 > #!/bin/sh
265 287 > echo "** custom diff **"
266 288 > EOF
267 289 $ chmod +x dir/tool.sh
268 290 $ tool=`pwd`/dir/tool.sh
269 291 $ hg --debug tl --config extdiff.tl= --config merge-tools.tl.executable=$tool
270 292 making snapshot of 2 files from rev * (glob)
271 293 a
272 294 b
273 295 making snapshot of 2 files from working directory
274 296 a
275 297 b
276 298 running '$TESTTMP/a/dir/tool.sh a.* a' in */extdiff.* (glob)
277 299 ** custom diff **
278 300 cleaning up temp directory
279 301 [1]
280 302
281 303 $ cd ..
282 304
283 305 #endif
284 306
285 307 #if symlink
286 308
287 309 Test symlinks handling (issue1909)
288 310
289 311 $ hg init testsymlinks
290 312 $ cd testsymlinks
291 313 $ echo a > a
292 314 $ hg ci -Am adda
293 315 adding a
294 316 $ echo a >> a
295 317 $ ln -s missing linka
296 318 $ hg add linka
297 319 $ hg falabala -r 0 --traceback
298 320 diffing testsymlinks.07f494440405 testsymlinks
299 321 [1]
300 322 $ cd ..
301 323
302 324 #endif
General Comments 0
You need to be logged in to leave comments. Login now