hgext/extdiff.py
changeset 23680 4075f2f8ea53
parent 23270 41c03b7592ed
child 23681 9476cb62298e
equal deleted inserted replaced
23679:dd1e73c4be13 23680:4075f2f8ea53
   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)