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) |