Mercurial > hgsubversion
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) |