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 |