Mercurial > hgsubversion
comparison fetch_command.py @ 129:59f8603a6641
fetch_command: in stupid mode, load file content on demand
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Wed, 10 Dec 2008 11:03:21 -0600 |
parents | bab5bcbbb3dc |
children | 2242dd1163c6 |
comparison
equal
deleted
inserted
replaced
128:bab5bcbbb3dc | 129:59f8603a6641 |
---|---|
178 patchfile.__init__(self, ui, fname, None, False) | 178 patchfile.__init__(self, ui, fname, None, False) |
179 | 179 |
180 def readlines(self, fname): | 180 def readlines(self, fname): |
181 if fname not in parentctx: | 181 if fname not in parentctx: |
182 raise IOError('Cannot find %r to patch' % fname) | 182 raise IOError('Cannot find %r to patch' % fname) |
183 return cStringIO.StringIO(parentctx[fname].data()).readlines() | 183 fctx = parentctx[fname] |
184 data = fctx.data() | |
185 if 'l' in fctx.flags(): | |
186 data = 'link ' + data | |
187 return cStringIO.StringIO(data).readlines() | |
184 | 188 |
185 def writelines(self, fname, lines): | 189 def writelines(self, fname, lines): |
186 files[fname] = ''.join(lines) | 190 files[fname] = ''.join(lines) |
187 | 191 |
188 def unlink(self, fname): | 192 def unlink(self, fname): |
224 if (hasattr(e, 'apr_err') and e.apr_err != 160013): | 228 if (hasattr(e, 'apr_err') and e.apr_err != 160013): |
225 raise | 229 raise |
226 raise BadPatchApply('previous revision does not exist') | 230 raise BadPatchApply('previous revision does not exist') |
227 files_data = {} | 231 files_data = {} |
228 binary_files = {} | 232 binary_files = {} |
233 touched_files = {} | |
229 for m in binary_file_re.findall(d): | 234 for m in binary_file_re.findall(d): |
230 # we have to pull each binary file by hand as a fulltext, | 235 # we have to pull each binary file by hand as a fulltext, |
231 # which sucks but we've got no choice | 236 # which sucks but we've got no choice |
232 binary_files[m] = 1 | 237 binary_files[m] = 1 |
233 files_data[m] = '' | 238 touched_files[m] = 1 |
234 d2 = empty_file_patch_wont_make_re.sub('', d) | 239 d2 = empty_file_patch_wont_make_re.sub('', d) |
235 d2 = property_exec_set_re.sub('', d2) | 240 d2 = property_exec_set_re.sub('', d2) |
236 d2 = property_exec_removed_re.sub('', d2) | 241 d2 = property_exec_removed_re.sub('', d2) |
237 for f in any_file_re.findall(d): | 242 for f in any_file_re.findall(d): |
238 if f in files_data: | |
239 continue | |
240 # Here we ensure that all files, including the new empty ones | 243 # Here we ensure that all files, including the new empty ones |
241 # will be marked with proper data. | 244 # are marked as touched. Content is loaded on demand. |
242 # TODO: load file data when necessary | 245 touched_files[f] = 1 |
243 files_data[f] = '' | |
244 if f in parentctx: | |
245 files_data[f] = parentctx[f].data() | |
246 if d2.strip() and len(re.findall('\n[-+]', d2.strip())) > 0: | 246 if d2.strip() and len(re.findall('\n[-+]', d2.strip())) > 0: |
247 try: | 247 try: |
248 oldpatchfile = patch.patchfile | 248 oldpatchfile = patch.patchfile |
249 patch.patchfile = mempatchproxy(parentctx, files_data) | 249 patch.patchfile = mempatchproxy(parentctx, files_data) |
250 try: | 250 try: |
264 for x in files_data.iterkeys(): | 264 for x in files_data.iterkeys(): |
265 ui.status('M %s\n' % x) | 265 ui.status('M %s\n' % x) |
266 # if this patch didn't apply right, fall back to exporting the | 266 # if this patch didn't apply right, fall back to exporting the |
267 # entire rev. | 267 # entire rev. |
268 if patch_st == -1: | 268 if patch_st == -1: |
269 for fn in files_data: | |
270 if 'l' in parentctx.flags(fn): | |
271 # I think this might be an underlying bug in svn - | |
272 # I get diffs of deleted symlinks even though I | |
273 # specifically said no deletes above. | |
274 raise BadPatchApply('deleted symlinked prevent patching') | |
275 assert False, ('This should only happen on case-insensitive' | 269 assert False, ('This should only happen on case-insensitive' |
276 ' volumes.') | 270 ' volumes.') |
277 elif patch_st == 1: | 271 elif patch_st == 1: |
278 # When converting Django, I saw fuzz on .po files that was | 272 # When converting Django, I saw fuzz on .po files that was |
279 # causing revisions to end up failing verification. If that | 273 # causing revisions to end up failing verification. If that |
287 for m in property_exec_removed_re.findall(d): | 281 for m in property_exec_removed_re.findall(d): |
288 exec_files[m] = False | 282 exec_files[m] = False |
289 for m in property_exec_set_re.findall(d): | 283 for m in property_exec_set_re.findall(d): |
290 exec_files[m] = True | 284 exec_files[m] = True |
291 for m in exec_files: | 285 for m in exec_files: |
292 if m in files_data: | 286 touched_files[m] = 1 |
293 continue | |
294 data = '' | |
295 if m in parentctx: | |
296 data = parentctx[m].data() | |
297 files_data[m] = data | |
298 link_files = {} | 287 link_files = {} |
299 for m in property_special_set_re.findall(d): | 288 for m in property_special_set_re.findall(d): |
300 # TODO(augie) when a symlink is removed, patching will fail. | 289 # TODO(augie) when a symlink is removed, patching will fail. |
301 # We're seeing that above - there's gotta be a better | 290 # We're seeing that above - there's gotta be a better |
302 # workaround than just bailing like that. | 291 # workaround than just bailing like that. |
303 assert m in files_data | 292 assert m in files_data |
304 files_data[m] = files_data[m][len('link '):] | |
305 link_files[m] = True | 293 link_files[m] = True |
294 for m in property_special_removed_re.findall(d): | |
295 assert m in files_data | |
296 link_files[m] = False | |
306 | 297 |
307 for p in r.paths: | 298 for p in r.paths: |
308 if p.startswith(diff_path) and r.paths[p].action == 'D': | 299 if p.startswith(diff_path) and r.paths[p].action == 'D': |
309 p2 = p[len(diff_path)+1:].strip('/') | 300 p2 = p[len(diff_path)+1:].strip('/') |
310 if p2 in parentctx: | 301 if p2 in parentctx: |
311 files_data[p2] = None | 302 files_data[p2] = None |
312 continue | 303 continue |
313 # If this isn't in the parent ctx, it must've been a dir | 304 # If this isn't in the parent ctx, it must've been a dir |
314 files_data.update([(f, None) for f in parentctx if f.startswith(p2 + '/')]) | 305 files_data.update([(f, None) for f in parentctx if f.startswith(p2 + '/')]) |
315 | 306 |
316 copies = getcopies(svn, hg_editor, branch, diff_path, r, files_data, | 307 for f in files_data: |
308 touched_files[f] = 1 | |
309 | |
310 copies = getcopies(svn, hg_editor, branch, diff_path, r, touched_files, | |
317 parentctx) | 311 parentctx) |
318 | 312 |
319 def filectxfn(repo, memctx, path): | 313 def filectxfn(repo, memctx, path): |
320 data = files_data[path] | 314 if path in files_data and files_data[path] is None: |
321 if data is None: | |
322 raise IOError() | 315 raise IOError() |
323 if path not in binary_files: | 316 |
324 isexe = exec_files.get(path, 'x' in parentctx.flags(path)) | 317 if path in binary_files: |
325 islink = path in link_files | |
326 else: | |
327 data, mode = svn.get_file(diff_path + '/' + path, r.revnum) | 318 data, mode = svn.get_file(diff_path + '/' + path, r.revnum) |
328 isexe = 'x' in mode | 319 isexe = 'x' in mode |
329 islink = 'l' in mode | 320 islink = 'l' in mode |
321 else: | |
322 isexe = exec_files.get(path, 'x' in parentctx.flags(path)) | |
323 islink = link_files.get(path, 'l' in parentctx.flags(path)) | |
324 data = '' | |
325 if path in files_data: | |
326 data = files_data[path] | |
327 if islink: | |
328 data = data[len('link '):] | |
329 elif path in parentctx: | |
330 data = parentctx[path].data() | |
331 | |
330 copied = copies.get(path) | 332 copied = copies.get(path) |
331 return context.memfilectx(path=path, data=data, islink=islink, | 333 return context.memfilectx(path=path, data=data, islink=islink, |
332 isexec=isexe, copied=copied) | 334 isexec=isexe, copied=copied) |
333 | 335 |
334 return list(files_data), filectxfn | 336 return list(touched_files), filectxfn |
335 | 337 |
336 def makecopyfinder(r, branchpath, rootdir): | 338 def makecopyfinder(r, branchpath, rootdir): |
337 """Return a function detecting copies. | 339 """Return a function detecting copies. |
338 | 340 |
339 Returned copyfinder(path) returns None if no copy information can | 341 Returned copyfinder(path) returns None if no copy information can |