107 if node is None: |
107 if node is None: |
108 fns_and_mtime.append((dest, repo.wjoin(fn), |
108 fns_and_mtime.append((dest, repo.wjoin(fn), |
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 |
116 - copy to a temp structure if diffing working revision with |
116 - copy to a temp structure if diffing working revision with |
117 another one and more than 1 file is changed |
117 another one and more than 1 file is changed |
118 - just invoke the diff for a single file in the working dir |
118 - just invoke the diff for a single file in the working dir |
119 ''' |
119 ''' |
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: |
127 msg = _('cannot specify --rev and --change at the same time') |
126 msg = _('cannot specify --rev and --change at the same time') |
128 raise util.Abort(msg) |
127 raise util.Abort(msg) |
220 |
219 |
221 # Match parent2 first, so 'parent1?' will match both parent1 and parent |
220 # Match parent2 first, so 'parent1?' will match both parent1 and parent |
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) |
230 |
228 |
231 for copy_fn, working_fn, mtime in fns_and_mtime: |
229 for copy_fn, working_fn, mtime in fns_and_mtime: |
269 program = opts.get('program') |
267 program = opts.get('program') |
270 option = opts.get('option') |
268 option = opts.get('option') |
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'): |
278 if cmd.startswith('cmd.'): |
277 if cmd.startswith('cmd.'): |
279 cmd = cmd[4:] |
278 cmd = cmd[4:] |
280 if not path: |
279 if not path: |
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 |
310 Show differences between revisions for the specified files, using |
317 Show differences between revisions for the specified files, using |
311 the %(path)s program. |
318 the %(path)s program. |
323 # fail when the docstring contains non-ASCII characters. |
330 # fail when the docstring contains non-ASCII characters. |
324 # Decoding the string to a Unicode string here (using the |
331 # Decoding the string to a Unicode string here (using the |
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) |