hgext/extdiff.py
changeset 5108 1830bc7676ee
parent 4730 eadfaa9ec487
child 5109 841568ccc09d
equal deleted inserted replaced
5107:c14968344d19 5108:1830bc7676ee
    51 from mercurial.i18n import _
    51 from mercurial.i18n import _
    52 from mercurial.node import *
    52 from mercurial.node import *
    53 from mercurial import cmdutil, util
    53 from mercurial import cmdutil, util
    54 import os, shutil, tempfile
    54 import os, shutil, tempfile
    55 
    55 
       
    56 
       
    57 def snapshot_node(ui, repo, files, node, tmproot):
       
    58     '''snapshot files as of some revision'''
       
    59     mf = repo.changectx(node).manifest()
       
    60     dirname = os.path.basename(repo.root)
       
    61     if dirname == "":
       
    62         dirname = "root"
       
    63     dirname = '%s.%s' % (dirname, short(node))
       
    64     base = os.path.join(tmproot, dirname)
       
    65     os.mkdir(base)
       
    66     if not ui.quiet:
       
    67         ui.write_err(_('making snapshot of %d files from rev %s\n') %
       
    68                      (len(files), short(node)))
       
    69     for fn in files:
       
    70         if not fn in mf:
       
    71             # skipping new file after a merge ?
       
    72             continue
       
    73         wfn = util.pconvert(fn)
       
    74         ui.note('  %s\n' % wfn)
       
    75         dest = os.path.join(base, wfn)
       
    76         destdir = os.path.dirname(dest)
       
    77         if not os.path.isdir(destdir):
       
    78             os.makedirs(destdir)
       
    79         data = repo.wwritedata(wfn, repo.file(wfn).read(mf[wfn]))
       
    80         open(dest, 'wb').write(data)
       
    81     return dirname
       
    82 
       
    83 
       
    84 def snapshot_wdir(ui, repo, files, tmproot):
       
    85     '''snapshot files from working directory.
       
    86     if not using snapshot, -I/-X does not work and recursive diff
       
    87     in tools like kdiff3 and meld displays too many files.'''
       
    88     dirname = os.path.basename(repo.root)
       
    89     if dirname == "":
       
    90         dirname = "root"
       
    91     base = os.path.join(tmproot, dirname)
       
    92     os.mkdir(base)
       
    93     if not ui.quiet:
       
    94         ui.write_err(_('making snapshot of %d files from working dir\n') %
       
    95                      (len(files)))
       
    96     for fn in files:
       
    97         wfn = util.pconvert(fn)
       
    98         ui.note('  %s\n' % wfn)
       
    99         dest = os.path.join(base, wfn)
       
   100         destdir = os.path.dirname(dest)
       
   101         if not os.path.isdir(destdir):
       
   102             os.makedirs(destdir)
       
   103         fp = open(dest, 'wb')
       
   104         for chunk in util.filechunkiter(repo.wopener(wfn)):
       
   105             fp.write(chunk)
       
   106     return dirname
       
   107     
       
   108 
    56 def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
   109 def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
    57     def snapshot_node(files, node):
       
    58         '''snapshot files as of some revision'''
       
    59         mf = repo.changectx(node).manifest()
       
    60         dirname = os.path.basename(repo.root)
       
    61         if dirname == "":
       
    62             dirname = "root"
       
    63         dirname = '%s.%s' % (dirname, short(node))
       
    64         base = os.path.join(tmproot, dirname)
       
    65         os.mkdir(base)
       
    66         if not ui.quiet:
       
    67             ui.write_err(_('making snapshot of %d files from rev %s\n') %
       
    68                          (len(files), short(node)))
       
    69         for fn in files:
       
    70             if not fn in mf:
       
    71                 # skipping new file after a merge ?
       
    72                 continue
       
    73             wfn = util.pconvert(fn)
       
    74             ui.note('  %s\n' % wfn)
       
    75             dest = os.path.join(base, wfn)
       
    76             destdir = os.path.dirname(dest)
       
    77             if not os.path.isdir(destdir):
       
    78                 os.makedirs(destdir)
       
    79             data = repo.wwritedata(wfn, repo.file(wfn).read(mf[wfn]))
       
    80             open(dest, 'wb').write(data)
       
    81         return dirname
       
    82 
       
    83     def snapshot_wdir(files):
       
    84         '''snapshot files from working directory.
       
    85         if not using snapshot, -I/-X does not work and recursive diff
       
    86         in tools like kdiff3 and meld displays too many files.'''
       
    87         dirname = os.path.basename(repo.root)
       
    88         if dirname == "":
       
    89             dirname = "root"
       
    90         base = os.path.join(tmproot, dirname)
       
    91         os.mkdir(base)
       
    92         if not ui.quiet:
       
    93             ui.write_err(_('making snapshot of %d files from working dir\n') %
       
    94                          (len(files)))
       
    95         for fn in files:
       
    96             wfn = util.pconvert(fn)
       
    97             ui.note('  %s\n' % wfn)
       
    98             dest = os.path.join(base, wfn)
       
    99             destdir = os.path.dirname(dest)
       
   100             if not os.path.isdir(destdir):
       
   101                 os.makedirs(destdir)
       
   102             fp = open(dest, 'wb')
       
   103             for chunk in util.filechunkiter(repo.wopener(wfn)):
       
   104                 fp.write(chunk)
       
   105         return dirname
       
   106 
       
   107     node1, node2 = cmdutil.revpair(repo, opts['rev'])
   110     node1, node2 = cmdutil.revpair(repo, opts['rev'])
   108     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
   111     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
   109     modified, added, removed, deleted, unknown = repo.status(
   112     modified, added, removed, deleted, unknown = repo.status(
   110         node1, node2, files, match=matchfn)[:5]
   113         node1, node2, files, match=matchfn)[:5]
   111     if not (modified or added or removed):
   114     if not (modified or added or removed):
   112         return 0
   115         return 0
   113 
   116 
   114     tmproot = tempfile.mkdtemp(prefix='extdiff.')
   117     tmproot = tempfile.mkdtemp(prefix='extdiff.')
   115     try:
   118     try:
   116         dir1 = snapshot_node(modified + removed, node1)
   119         dir1 = snapshot_node(ui, repo, modified + removed, node1, tmproot)
   117         if node2:
   120         if node2:
   118             dir2 = snapshot_node(modified + added, node2)
   121             dir2 = snapshot_node(ui, repo, modified + added, node2, tmproot)
   119         else:
   122         else:
   120             dir2 = snapshot_wdir(modified + added)
   123             dir2 = snapshot_wdir(ui, repo, modified + added, tmproot)
   121         cmdline = ('%s %s %s %s' %
   124         cmdline = ('%s %s %s %s' %
   122                    (util.shellquote(diffcmd), ' '.join(diffopts),
   125                    (util.shellquote(diffcmd), ' '.join(diffopts),
   123                     util.shellquote(dir1), util.shellquote(dir2)))
   126                     util.shellquote(dir1), util.shellquote(dir2)))
   124         ui.debug('running %r in %s\n' % (cmdline, tmproot))
   127         ui.debug('running %r in %s\n' % (cmdline, tmproot))
   125         util.system(cmdline, cwd=tmproot)
   128         util.system(cmdline, cwd=tmproot)