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