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