##// END OF EJS Templates
extdiff: add --per-file and --confirm options...
Ludovic Chabant -
r41533:1aa52287 default draft
parent child Browse files
Show More
@@ -80,6 +80,7 b' from mercurial.node import ('
80 80 from mercurial import (
81 81 archival,
82 82 cmdutil,
83 encoding,
83 84 error,
84 85 filemerge,
85 86 formatter,
@@ -175,6 +176,65 b' def formatcmdline(cmdline, repo_root, do'
175 176 cmdline += ' $parent1 $child'
176 177 return re.sub(regex, quote, cmdline)
177 178
179 def _runperfilediff(cmdline, repo_root, ui, do3way, confirm,
180 commonfiles, tmproot, dir1a, dir1b,
181 dir2root, dir2,
182 rev1a, rev1b, rev2):
183 # Note that we need to sort the list of files because it was
184 # built in an "unstable" way and it's annoying to get files in a
185 # random order, especially when "confirm" mode is enabled.
186 totalfiles = len(commonfiles)
187 for idx, commonfile in enumerate(sorted(commonfiles)):
188 path1a = os.path.join(tmproot, dir1a, commonfile)
189 label1a = commonfile + rev1a
190 if not os.path.isfile(path1a):
191 path1a = os.devnull
192
193 path1b = ''
194 label1b = ''
195 if do3way:
196 path1b = os.path.join(tmproot, dir1b, commonfile)
197 label1b = commonfile + rev1b
198 if not os.path.isfile(path1b):
199 path1b = os.devnull
200
201 path2 = os.path.join(dir2root, dir2, commonfile)
202 label2 = commonfile + rev2
203
204 if confirm:
205 # Prompt before showing this diff
206 difffiles = _('diff %s (%d of %d)') % (commonfile, idx + 1,
207 totalfiles)
208 responses = _('[Yns?]'
209 '$$ &Yes, show diff'
210 '$$ &No, skip this diff'
211 '$$ &Skip remaining diffs'
212 '$$ &? (display help)')
213 r = ui.promptchoice('%s %s' % (difffiles, responses))
214 if r == 3: # ?
215 while r == 3:
216 for c, t in ui.extractchoices(responses)[1]:
217 ui.write('%s - %s\n' % (c, encoding.lower(t)))
218 r = ui.promptchoice('%s %s' % (difffiles, responses))
219 if r == 0: # yes
220 pass
221 elif r == 1: # no
222 continue
223 elif r == 2: # skip
224 break
225
226 curcmdline = formatcmdline(
227 cmdline, repo_root, do3way=do3way,
228 parent1=path1a, plabel1=label1a,
229 parent2=path1b, plabel2=label1b,
230 child=path2, clabel=label2)
231 ui.debug('running %r in %s\n' % (pycompat.bytestr(curcmdline),
232 tmproot))
233
234 # Run the comparison program and wait for it to exit
235 # before we show the next file.
236 ui.system(curcmdline, cwd=tmproot, blockedtag='extdiff')
237
178 238 def dodiff(ui, repo, cmdline, pats, opts):
179 239 '''Do the actual diff:
180 240
@@ -201,6 +261,9 b' def dodiff(ui, repo, cmdline, pats, opts'
201 261 else:
202 262 ctx1b = repo[nullid]
203 263
264 perfile = opts.get('per_file')
265 confirm = opts.get('confirm')
266
204 267 node1a = ctx1a.node()
205 268 node1b = ctx1b.node()
206 269 node2 = ctx2.node()
@@ -217,6 +280,8 b' def dodiff(ui, repo, cmdline, pats, opts'
217 280 if opts.get('patch'):
218 281 if subrepos:
219 282 raise error.Abort(_('--patch cannot be used with --subrepos'))
283 if perfile:
284 raise error.Abort(_('--patch cannot be used with --per-file'))
220 285 if node2 is None:
221 286 raise error.Abort(_('--patch requires two revisions'))
222 287 else:
@@ -304,15 +369,23 b' def dodiff(ui, repo, cmdline, pats, opts'
304 369 label1b = None
305 370 fnsandstat = []
306 371
307 # Run the external tool on the 2 temp directories or the patches
308 cmdline = formatcmdline(
309 cmdline, repo.root, do3way=do3way,
310 parent1=dir1a, plabel1=label1a,
311 parent2=dir1b, plabel2=label1b,
312 child=dir2, clabel=label2)
313 ui.debug('running %r in %s\n' % (pycompat.bytestr(cmdline),
314 tmproot))
315 ui.system(cmdline, cwd=tmproot, blockedtag='extdiff')
372 if not perfile:
373 # Run the external tool on the 2 temp directories or the patches
374 cmdline = formatcmdline(
375 cmdline, repo.root, do3way=do3way,
376 parent1=dir1a, plabel1=label1a,
377 parent2=dir1b, plabel2=label1b,
378 child=dir2, clabel=label2)
379 ui.debug('running %r in %s\n' % (pycompat.bytestr(cmdline),
380 tmproot))
381 ui.system(cmdline, cwd=tmproot, blockedtag='extdiff')
382 else:
383 # Run the external tool once for each pair of files
384 _runperfilediff(
385 cmdline, repo.root, ui, do3way=do3way, confirm=confirm,
386 commonfiles=common, tmproot=tmproot, dir1a=dir1a, dir1b=dir1b,
387 dir2root=dir2root, dir2=dir2,
388 rev1a=rev1a, rev1b=rev1b, rev2=rev2)
316 389
317 390 for copy_fn, working_fn, st in fnsandstat:
318 391 cpstat = os.lstat(copy_fn)
@@ -340,6 +413,10 b' extdiffopts = ['
340 413 _('pass option to comparison program'), _('OPT')),
341 414 ('r', 'rev', [], _('revision'), _('REV')),
342 415 ('c', 'change', '', _('change made by revision'), _('REV')),
416 ('', 'per-file', False,
417 _('compare each file instead of revision snapshots')),
418 ('', 'confirm', False,
419 _('prompt user before each external program invocation')),
343 420 ('', 'patch', None, _('compare patches for two revisions'))
344 421 ] + cmdutil.walkopts + cmdutil.subrepoopts
345 422
@@ -357,15 +434,23 b' def extdiff(ui, repo, *pats, **opts):'
357 434 default options "-Npru".
358 435
359 436 To select a different program, use the -p/--program option. The
360 program will be passed the names of two directories to compare. To
361 pass additional options to the program, use -o/--option. These
362 will be passed before the names of the directories to compare.
437 program will be passed the names of two directories to compare,
438 unless the --per-file option is specified (see below). To pass
439 additional options to the program, use -o/--option. These will be
440 passed before the names of the directories or files to compare.
363 441
364 442 When two revision arguments are given, then changes are shown
365 443 between those revisions. If only one revision is specified then
366 444 that revision is compared to the working directory, and, when no
367 445 revisions are specified, the working directory files are compared
368 to its parent.'''
446 to its parent.
447
448 The --per-file option runs the external program repeatedly on each
449 file to diff, instead of once on two directories.
450
451 The --confirm option will prompt the user before each invocation of
452 the external program. It is ignored if --per-file isn't specified.
453 '''
369 454 opts = pycompat.byteskwargs(opts)
370 455 program = opts.get('program')
371 456 option = opts.get('option')
@@ -48,6 +48,8 b' Should diff cloned directories:'
48 48 -o --option OPT [+] pass option to comparison program
49 49 -r --rev REV [+] revision
50 50 -c --change REV change made by revision
51 --per-file compare each file instead of revision snapshots
52 --confirm prompt user before each external program invocation
51 53 --patch compare patches for two revisions
52 54 -I --include PATTERN [+] include names matching the given patterns
53 55 -X --exclude PATTERN [+] exclude names matching the given patterns
@@ -128,6 +130,40 b' issue3153: ensure using extdiff with rem'
128 130 diffing a.398e36faf9c6 a.5ab95fb166c4
129 131 [1]
130 132
133 Test --per-file option:
134
135 $ hg up -q -C 3
136 $ echo a2 > a
137 $ echo b2 > b
138 $ hg ci -d '3 0' -mtestmode1
139 created new head
140 $ hg falabala -c 6 --per-file
141 diffing "*\\extdiff.*\\a.46c0e4daeb72\\a" "a.81906f2b98ac\\a" (glob) (windows !)
142 diffing */extdiff.*/a.46c0e4daeb72/a a.81906f2b98ac/a (glob) (no-windows !)
143 diffing "*\\extdiff.*\\a.46c0e4daeb72\\b" "a.81906f2b98ac\\b" (glob) (windows !)
144 diffing */extdiff.*/a.46c0e4daeb72/b a.81906f2b98ac/b (glob) (no-windows !)
145 [1]
146
147 Test --per-file and --confirm options:
148
149 $ hg --config ui.interactive=True falabala -c 6 --per-file --confirm <<EOF
150 > n
151 > y
152 > EOF
153 diff a (1 of 2) [Yns?] n
154 diff b (2 of 2) [Yns?] y
155 diffing "*\\extdiff.*\\a.46c0e4daeb72\\b" "a.81906f2b98ac\\b" (glob) (windows !)
156 diffing */extdiff.*/a.46c0e4daeb72/b a.81906f2b98ac/b (glob) (no-windows !)
157 [1]
158
159 Test --per-file and --confirm options with skipping:
160
161 $ hg --config ui.interactive=True falabala -c 6 --per-file --confirm <<EOF
162 > s
163 > EOF
164 diff a (1 of 2) [Yns?] s
165 [1]
166
131 167 issue4463: usage of command line configuration without additional quoting
132 168
133 169 $ cat <<EOF >> $HGRCPATH
@@ -805,15 +805,22 b' Extension module help vs command help:'
805 805 "-Npru".
806 806
807 807 To select a different program, use the -p/--program option. The program
808 will be passed the names of two directories to compare. To pass additional
809 options to the program, use -o/--option. These will be passed before the
810 names of the directories to compare.
808 will be passed the names of two directories to compare, unless the --per-
809 file option is specified (see below). To pass additional options to the
810 program, use -o/--option. These will be passed before the names of the
811 directories or files to compare.
811 812
812 813 When two revision arguments are given, then changes are shown between
813 814 those revisions. If only one revision is specified then that revision is
814 815 compared to the working directory, and, when no revisions are specified,
815 816 the working directory files are compared to its parent.
816 817
818 The --per-file option runs the external program repeatedly on each file to
819 diff, instead of once on two directories.
820
821 The --confirm option will prompt the user before each invocation of the
822 external program. It is ignored if --per-file isn't specified.
823
817 824 (use 'hg help -e extdiff' to show help for the extdiff extension)
818 825
819 826 options ([+] can be repeated):
@@ -822,6 +829,8 b' Extension module help vs command help:'
822 829 -o --option OPT [+] pass option to comparison program
823 830 -r --rev REV [+] revision
824 831 -c --change REV change made by revision
832 --per-file compare each file instead of revision snapshots
833 --confirm prompt user before each external program invocation
825 834 --patch compare patches for two revisions
826 835 -I --include PATTERN [+] include names matching the given patterns
827 836 -X --exclude PATTERN [+] exclude names matching the given patterns
General Comments 0
You need to be logged in to leave comments. Login now