Mercurial > hg
comparison hgext/extdiff.py @ 6103:e668fd796b8b
Propagating changes back to working dirs when changing files in external
author | Fabio Zadrozny <fabiofz at gmail dot com> |
---|---|
date | Sun, 26 Aug 2007 21:31:18 -0300 |
parents | 32ec518ee3cb |
children | f89fd07fc51d |
comparison
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 |