comparison hg_delta_editor.py @ 97:0d3a2a7cefa3

hg_delta_editor: fix symlink prefix confusion - SubversionRepo.get_file() strips the symlink prefix - Enforce that hg_delta_editor symlink data always contains the prefix. The alternative was seducing and more consistent with hg content but it makes the code more complicated since svn:special can be set before or after the content is set, and we need it in apply_textdelta() This issue fixes jQuery repository conversion at r3674.
author Patrick Mezard <pmezard@gmail.com>
date Thu, 20 Nov 2008 22:41:15 -0600
parents 9c1b53abefcb
children 5497d1264b4d
comparison
equal deleted inserted replaced
96:9b5e528f67f8 97:0d3a2a7cefa3
120 120
121 def clear_current_info(self): 121 def clear_current_info(self):
122 '''Clear the info relevant to a replayed revision so that the next 122 '''Clear the info relevant to a replayed revision so that the next
123 revision can be replayed. 123 revision can be replayed.
124 ''' 124 '''
125 # Map files to raw svn data (symlink prefix is preserved)
125 self.current_files = {} 126 self.current_files = {}
126 self.deleted_files = {} 127 self.deleted_files = {}
127 self.current_rev = None 128 self.current_rev = None
128 self.current_files_exec = {} 129 self.current_files_exec = {}
129 self.current_files_symlink = {} 130 self.current_files_symlink = {}
178 179
179 def set_current_rev(self, rev): 180 def set_current_rev(self, rev):
180 '''Set the revision we're currently converting. 181 '''Set the revision we're currently converting.
181 ''' 182 '''
182 self.current_rev = rev 183 self.current_rev = rev
184
185 def set_file(self, path, data, isexec=False, islink=False):
186 if islink:
187 data = 'link ' + data
188 self.current_files[path] = data
189 self.current_files_exec[path] = isexec
190 self.current_files_symlink[path] = islink
183 191
184 def _normalize_path(self, path): 192 def _normalize_path(self, path):
185 '''Normalize a path to strip of leading slashes and our subdir if we 193 '''Normalize a path to strip of leading slashes and our subdir if we
186 have one. 194 have one.
187 ''' 195 '''
360 current_file = files[path] 368 current_file = files[path]
361 if current_file in self.deleted_files: 369 if current_file in self.deleted_files:
362 raise IOError() 370 raise IOError()
363 copied = self.copies.get(current_file) 371 copied = self.copies.get(current_file)
364 flags = parent_ctx.flags(path) 372 flags = parent_ctx.flags(path)
365 is_exec = self.current_files_exec.get(current_file, 373 is_exec = self.current_files_exec.get(current_file, 'x' in flags)
366 'x' in flags) 374 is_link = self.current_files_symlink.get(current_file, 'l' in flags)
367 is_link = self.current_files_symlink.get(current_file,
368 'l' in flags)
369 if current_file in self.current_files: 375 if current_file in self.current_files:
370 data = self.current_files[current_file] 376 data = self.current_files[current_file]
371 if is_link: 377 if is_link:
372 assert data.startswith('link ') 378 assert data.startswith('link ')
373 data = data[len('link '):] 379 data = data[len('link '):]
549 ha = self.get_parent_revision(copyfrom_revision + 1, 555 ha = self.get_parent_revision(copyfrom_revision + 1,
550 from_branch) 556 from_branch)
551 ctx = self.repo.changectx(ha) 557 ctx = self.repo.changectx(ha)
552 if from_file in ctx: 558 if from_file in ctx:
553 fctx = ctx.filectx(from_file) 559 fctx = ctx.filectx(from_file)
560 flags = fctx.flags()
554 cur_file = self.current_file 561 cur_file = self.current_file
555 self.current_files[cur_file] = fctx.data() 562 self.set_file(cur_file, fctx.data(), 'x' in flags, 'l' in flags)
556 self.current_files_symlink[cur_file] = 'l' in fctx.flags()
557 self.current_files_exec[cur_file] = 'x' in fctx.flags()
558 if from_branch == branch: 563 if from_branch == branch:
559 parentid = self.get_parent_revision(self.current_rev.revnum, 564 parentid = self.get_parent_revision(self.current_rev.revnum,
560 branch) 565 branch)
561 if parentid != revlog.nullid: 566 if parentid != revlog.nullid:
562 parentctx = self.repo.changectx(parentid) 567 parentctx = self.repo.changectx(parentid)
603 if not f.startswith(cp_f): 608 if not f.startswith(cp_f):
604 continue 609 continue
605 f2 = f[len(cp_f):] 610 f2 = f[len(cp_f):]
606 fctx = cp_f_ctx.filectx(f) 611 fctx = cp_f_ctx.filectx(f)
607 fp_c = path + '/' + f2 612 fp_c = path + '/' + f2
608 self.current_files[fp_c] = fctx.data() 613 self.set_file(fp_c, fctx.data(), 'x' in fctx.flags(), 'l' in fctx.flags())
609 self.current_files_exec[fp_c] = 'x' in fctx.flags()
610 self.current_files_symlink[fp_c] = 'l' in fctx.flags()
611 if fp_c in self.deleted_files: 614 if fp_c in self.deleted_files:
612 del self.deleted_files[fp_c] 615 del self.deleted_files[fp_c]
613 if branch == source_branch: 616 if branch == source_branch:
614 copies[fp_c] = f 617 copies[fp_c] = f
615 if copies: 618 if copies:
654 ctx = self.repo.changectx(ha) 657 ctx = self.repo.changectx(ha)
655 if not p_ in ctx: 658 if not p_ in ctx:
656 self.missing_plaintexts.add(self.current_file) 659 self.missing_plaintexts.add(self.current_file)
657 # short circuit exit since we can't do anything anyway 660 # short circuit exit since we can't do anything anyway
658 return lambda x: None 661 return lambda x: None
659 base = ctx.filectx(p_).data() 662 fctx = ctx[p_]
663 base = fctx.data()
664 if 'l' in fctx.flags():
665 base = 'link ' + base
660 source = cStringIO.StringIO(base) 666 source = cStringIO.StringIO(base)
661 target = cStringIO.StringIO() 667 target = cStringIO.StringIO()
662 self.stream = target 668 self.stream = target
663 669
664 handler, baton = delta.svn_txdelta_apply(source, target, None) 670 handler, baton = delta.svn_txdelta_apply(source, target, None)