hgext/extdiff.py
changeset 6103 e668fd796b8b
parent 5293 32ec518ee3cb
child 6211 f89fd07fc51d
equal deleted inserted replaced
6102:4e351c03a31a 6103:e668fd796b8b
    78 
    78 
    79 def snapshot_wdir(ui, repo, files, tmproot):
    79 def snapshot_wdir(ui, repo, files, tmproot):
    80     '''snapshot files from working directory.
    80     '''snapshot files from working directory.
    81     if not using snapshot, -I/-X does not work and recursive diff
    81     if not using snapshot, -I/-X does not work and recursive diff
    82     in tools like kdiff3 and meld displays too many files.'''
    82     in tools like kdiff3 and meld displays too many files.'''
    83     dirname = os.path.basename(repo.root)
    83     repo_root = repo.root
       
    84 
       
    85     dirname = os.path.basename(repo_root)
    84     if dirname == "":
    86     if dirname == "":
    85         dirname = "root"
    87         dirname = "root"
    86     base = os.path.join(tmproot, dirname)
    88     base = os.path.join(tmproot, dirname)
    87     os.mkdir(base)
    89     os.mkdir(base)
    88     ui.note(_('making snapshot of %d files from working dir\n') %
    90     ui.note(_('making snapshot of %d files from working dir\n') %
    89             (len(files)))
    91             (len(files)))
       
    92 
       
    93     fns_and_mtime = []
       
    94 
    90     for fn in files:
    95     for fn in files:
    91         wfn = util.pconvert(fn)
    96         wfn = util.pconvert(fn)
    92         ui.note('  %s\n' % wfn)
    97         ui.note('  %s\n' % wfn)
    93         dest = os.path.join(base, wfn)
    98         dest = os.path.join(base, wfn)
    94         destdir = os.path.dirname(dest)
    99         destdir = os.path.dirname(dest)
    95         if not os.path.isdir(destdir):
   100         if not os.path.isdir(destdir):
    96             os.makedirs(destdir)
   101             os.makedirs(destdir)
       
   102 
    97         fp = open(dest, 'wb')
   103         fp = open(dest, 'wb')
    98         for chunk in util.filechunkiter(repo.wopener(wfn)):
   104         for chunk in util.filechunkiter(repo.wopener(wfn)):
    99             fp.write(chunk)
   105             fp.write(chunk)
   100     return dirname
   106         fp.close()
       
   107 
       
   108         fns_and_mtime.append((dest, os.path.join(repo_root, fn),
       
   109             os.path.getmtime(dest)))
       
   110 
       
   111 
       
   112     return dirname, fns_and_mtime
   101 
   113 
   102 
   114 
   103 def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
   115 def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
       
   116     '''Do the actuall diff:
       
   117 
       
   118     - copy to a temp structure if diffing 2 internal revisions
       
   119     - copy to a temp structure if diffing working revision with
       
   120       another one and more than 1 file is changed
       
   121     - just invoke the diff for a single file in the working dir
       
   122     '''
   104     node1, node2 = cmdutil.revpair(repo, opts['rev'])
   123     node1, node2 = cmdutil.revpair(repo, opts['rev'])
   105     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
   124     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
   106     modified, added, removed, deleted, unknown = repo.status(
   125     modified, added, removed, deleted, unknown = repo.status(
   107         node1, node2, files, match=matchfn)[:5]
   126         node1, node2, files, match=matchfn)[:5]
   108     if not (modified or added or removed):
   127     if not (modified or added or removed):
   113     try:
   132     try:
   114         # Always make a copy of node1
   133         # Always make a copy of node1
   115         dir1 = snapshot_node(ui, repo, modified + removed, node1, tmproot)
   134         dir1 = snapshot_node(ui, repo, modified + removed, node1, tmproot)
   116         changes = len(modified) + len(removed) + len(added)
   135         changes = len(modified) + len(removed) + len(added)
   117 
   136 
       
   137         fns_and_mtime = []
       
   138 
   118         # If node2 in not the wc or there is >1 change, copy it
   139         # If node2 in not the wc or there is >1 change, copy it
   119         if node2:
   140         if node2:
   120             dir2 = snapshot_node(ui, repo, modified + added, node2, tmproot)
   141             dir2 = snapshot_node(ui, repo, modified + added, node2, tmproot)
   121         elif changes > 1:
   142         elif changes > 1:
   122             dir2 = snapshot_wdir(ui, repo, modified + added, tmproot)
   143             #we only actually need to get the files to copy back to the working
       
   144             #dir in this case (because the other cases are: diffing 2 revisions
       
   145             #or single file -- in which case the file is already directly passed
       
   146             #to the diff tool).
       
   147             dir2, fns_and_mtime = snapshot_wdir(ui, repo, modified + added, tmproot)
   123         else:
   148         else:
   124             # This lets the diff tool open the changed file directly
   149             # This lets the diff tool open the changed file directly
   125             dir2 = ''
   150             dir2 = ''
   126             dir2root = repo.root
   151             dir2root = repo.root
   127 
   152 
   140         cmdline = ('%s %s %s %s' %
   165         cmdline = ('%s %s %s %s' %
   141                    (util.shellquote(diffcmd), ' '.join(diffopts),
   166                    (util.shellquote(diffcmd), ' '.join(diffopts),
   142                     util.shellquote(dir1), util.shellquote(dir2)))
   167                     util.shellquote(dir1), util.shellquote(dir2)))
   143         ui.debug('running %r in %s\n' % (cmdline, tmproot))
   168         ui.debug('running %r in %s\n' % (cmdline, tmproot))
   144         util.system(cmdline, cwd=tmproot)
   169         util.system(cmdline, cwd=tmproot)
       
   170 
       
   171         for copy_fn, working_fn, mtime in fns_and_mtime:
       
   172             if os.path.getmtime(copy_fn) != mtime:
       
   173                 ui.debug('File changed while diffing. '
       
   174                          'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn))
       
   175                 util.copyfile(copy_fn, working_fn)
       
   176 
   145         return 1
   177         return 1
   146     finally:
   178     finally:
   147         ui.note(_('cleaning up temp directory\n'))
   179         ui.note(_('cleaning up temp directory\n'))
   148         shutil.rmtree(tmproot)
   180         shutil.rmtree(tmproot)
   149 
   181