##// END OF EJS Templates
extdiff: add --per-file and --confirm options...
Ludovic Chabant -
r41628:fa471151 default
parent child Browse files
Show More
@@ -80,6 +80,7 b' from mercurial.node import ('
80 from mercurial import (
80 from mercurial import (
81 archival,
81 archival,
82 cmdutil,
82 cmdutil,
83 encoding,
83 error,
84 error,
84 filemerge,
85 filemerge,
85 formatter,
86 formatter,
@@ -175,6 +176,65 b' def formatcmdline(cmdline, repo_root, do'
175 cmdline += ' $parent1 $child'
176 cmdline += ' $parent1 $child'
176 return re.sub(regex, quote, cmdline)
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 def dodiff(ui, repo, cmdline, pats, opts):
238 def dodiff(ui, repo, cmdline, pats, opts):
179 '''Do the actual diff:
239 '''Do the actual diff:
180
240
@@ -201,6 +261,9 b' def dodiff(ui, repo, cmdline, pats, opts'
201 else:
261 else:
202 ctx1b = repo[nullid]
262 ctx1b = repo[nullid]
203
263
264 perfile = opts.get('per_file')
265 confirm = opts.get('confirm')
266
204 node1a = ctx1a.node()
267 node1a = ctx1a.node()
205 node1b = ctx1b.node()
268 node1b = ctx1b.node()
206 node2 = ctx2.node()
269 node2 = ctx2.node()
@@ -217,6 +280,8 b' def dodiff(ui, repo, cmdline, pats, opts'
217 if opts.get('patch'):
280 if opts.get('patch'):
218 if subrepos:
281 if subrepos:
219 raise error.Abort(_('--patch cannot be used with --subrepos'))
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 if node2 is None:
285 if node2 is None:
221 raise error.Abort(_('--patch requires two revisions'))
286 raise error.Abort(_('--patch requires two revisions'))
222 else:
287 else:
@@ -304,15 +369,23 b' def dodiff(ui, repo, cmdline, pats, opts'
304 label1b = None
369 label1b = None
305 fnsandstat = []
370 fnsandstat = []
306
371
307 # Run the external tool on the 2 temp directories or the patches
372 if not perfile:
308 cmdline = formatcmdline(
373 # Run the external tool on the 2 temp directories or the patches
309 cmdline, repo.root, do3way=do3way,
374 cmdline = formatcmdline(
310 parent1=dir1a, plabel1=label1a,
375 cmdline, repo.root, do3way=do3way,
311 parent2=dir1b, plabel2=label1b,
376 parent1=dir1a, plabel1=label1a,
312 child=dir2, clabel=label2)
377 parent2=dir1b, plabel2=label1b,
313 ui.debug('running %r in %s\n' % (pycompat.bytestr(cmdline),
378 child=dir2, clabel=label2)
314 tmproot))
379 ui.debug('running %r in %s\n' % (pycompat.bytestr(cmdline),
315 ui.system(cmdline, cwd=tmproot, blockedtag='extdiff')
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 for copy_fn, working_fn, st in fnsandstat:
390 for copy_fn, working_fn, st in fnsandstat:
318 cpstat = os.lstat(copy_fn)
391 cpstat = os.lstat(copy_fn)
@@ -340,6 +413,10 b' extdiffopts = ['
340 _('pass option to comparison program'), _('OPT')),
413 _('pass option to comparison program'), _('OPT')),
341 ('r', 'rev', [], _('revision'), _('REV')),
414 ('r', 'rev', [], _('revision'), _('REV')),
342 ('c', 'change', '', _('change made by revision'), _('REV')),
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 ('', 'patch', None, _('compare patches for two revisions'))
420 ('', 'patch', None, _('compare patches for two revisions'))
344 ] + cmdutil.walkopts + cmdutil.subrepoopts
421 ] + cmdutil.walkopts + cmdutil.subrepoopts
345
422
@@ -357,15 +434,23 b' def extdiff(ui, repo, *pats, **opts):'
357 default options "-Npru".
434 default options "-Npru".
358
435
359 To select a different program, use the -p/--program option. The
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
437 program will be passed the names of two directories to compare,
361 pass additional options to the program, use -o/--option. These
438 unless the --per-file option is specified (see below). To pass
362 will be passed before the names of the directories to compare.
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 When two revision arguments are given, then changes are shown
442 When two revision arguments are given, then changes are shown
365 between those revisions. If only one revision is specified then
443 between those revisions. If only one revision is specified then
366 that revision is compared to the working directory, and, when no
444 that revision is compared to the working directory, and, when no
367 revisions are specified, the working directory files are compared
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 opts = pycompat.byteskwargs(opts)
454 opts = pycompat.byteskwargs(opts)
370 program = opts.get('program')
455 program = opts.get('program')
371 option = opts.get('option')
456 option = opts.get('option')
@@ -48,6 +48,8 b' Should diff cloned directories:'
48 -o --option OPT [+] pass option to comparison program
48 -o --option OPT [+] pass option to comparison program
49 -r --rev REV [+] revision
49 -r --rev REV [+] revision
50 -c --change REV change made by revision
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 --patch compare patches for two revisions
53 --patch compare patches for two revisions
52 -I --include PATTERN [+] include names matching the given patterns
54 -I --include PATTERN [+] include names matching the given patterns
53 -X --exclude PATTERN [+] exclude names matching the given patterns
55 -X --exclude PATTERN [+] exclude names matching the given patterns
@@ -128,6 +130,40 b' issue3153: ensure using extdiff with rem'
128 diffing a.398e36faf9c6 a.5ab95fb166c4
130 diffing a.398e36faf9c6 a.5ab95fb166c4
129 [1]
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 issue4463: usage of command line configuration without additional quoting
167 issue4463: usage of command line configuration without additional quoting
132
168
133 $ cat <<EOF >> $HGRCPATH
169 $ cat <<EOF >> $HGRCPATH
@@ -805,15 +805,22 b' Extension module help vs command help:'
805 "-Npru".
805 "-Npru".
806
806
807 To select a different program, use the -p/--program option. The program
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
808 will be passed the names of two directories to compare, unless the --per-
809 options to the program, use -o/--option. These will be passed before the
809 file option is specified (see below). To pass additional options to the
810 names of the directories to compare.
810 program, use -o/--option. These will be passed before the names of the
811 directories or files to compare.
811
812
812 When two revision arguments are given, then changes are shown between
813 When two revision arguments are given, then changes are shown between
813 those revisions. If only one revision is specified then that revision is
814 those revisions. If only one revision is specified then that revision is
814 compared to the working directory, and, when no revisions are specified,
815 compared to the working directory, and, when no revisions are specified,
815 the working directory files are compared to its parent.
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 (use 'hg help -e extdiff' to show help for the extdiff extension)
824 (use 'hg help -e extdiff' to show help for the extdiff extension)
818
825
819 options ([+] can be repeated):
826 options ([+] can be repeated):
@@ -822,6 +829,8 b' Extension module help vs command help:'
822 -o --option OPT [+] pass option to comparison program
829 -o --option OPT [+] pass option to comparison program
823 -r --rev REV [+] revision
830 -r --rev REV [+] revision
824 -c --change REV change made by revision
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 --patch compare patches for two revisions
834 --patch compare patches for two revisions
826 -I --include PATTERN [+] include names matching the given patterns
835 -I --include PATTERN [+] include names matching the given patterns
827 -X --exclude PATTERN [+] exclude names matching the given patterns
836 -X --exclude PATTERN [+] exclude names matching the given patterns
General Comments 0
You need to be logged in to leave comments. Login now