Mercurial > hgsubversion
comparison hg_delta_editor.py @ 304:ce676eff002b
First merge, totally untested.
| author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
|---|---|
| date | Fri, 01 May 2009 10:28:59 +0200 |
| parents | 4aba7542f6a9 153266401676 |
| children | e6853c7fa3af |
comparison
equal
deleted
inserted
replaced
| 303:f423a8780832 | 304:ce676eff002b |
|---|---|
| 6 import traceback | 6 import traceback |
| 7 | 7 |
| 8 from mercurial import context | 8 from mercurial import context |
| 9 from mercurial import hg | 9 from mercurial import hg |
| 10 from mercurial import ui | 10 from mercurial import ui |
| 11 from mercurial import util | 11 from mercurial import util as hgutil |
| 12 from mercurial import revlog | 12 from mercurial import revlog |
| 13 from mercurial import node | 13 from mercurial import node |
| 14 from svn import delta | 14 from svn import delta |
| 15 from svn import core | 15 from svn import core |
| 16 | 16 |
| 17 import svnexternals | 17 import svnexternals |
| 18 import util as our_util | 18 import util |
| 19 | 19 |
| 20 def pickle_atomic(data, file_path, dir=None): | 20 def pickle_atomic(data, file_path, dir=None): |
| 21 """pickle some data to a path atomically. | 21 """pickle some data to a path atomically. |
| 22 | 22 |
| 23 This is present because I kept corrupting my revmap by managing to hit ^C | 23 This is present because I kept corrupting my revmap by managing to hit ^C |
| 29 pickle.dump(data, f) | 29 pickle.dump(data, f) |
| 30 f.close() | 30 f.close() |
| 31 except: #pragma: no cover | 31 except: #pragma: no cover |
| 32 raise | 32 raise |
| 33 else: | 33 else: |
| 34 util.rename(path, file_path) | 34 hgutil.rename(path, file_path) |
| 35 | 35 |
| 36 def stash_exception_on_self(fn): | 36 def stash_exception_on_self(fn): |
| 37 """Stash any exception raised in the method on self. | 37 """Stash any exception raised in the method on self. |
| 38 | 38 |
| 39 This is required because the SWIG bindings just mutate any exception into | 39 This is required because the SWIG bindings just mutate any exception into |
| 58 f.flush() | 58 f.flush() |
| 59 f.close() | 59 f.close() |
| 60 self.revmap[revnum, branch] = node_hash | 60 self.revmap[revnum, branch] = node_hash |
| 61 | 61 |
| 62 def last_known_revision(self): | 62 def last_known_revision(self): |
| 63 ''' Obtain the highest numbered -- i.e. latest -- revision known. | 63 """Obtain the highest numbered -- i.e. latest -- revision known. |
| 64 | 64 |
| 65 Currently, this function just iterates over the entire revision map | 65 Currently, this function just iterates over the entire revision map |
| 66 using the max() builtin. This may be slow for extremely large | 66 using the max() builtin. This may be slow for extremely large |
| 67 repositories, but for now, it's fast enough. | 67 repositories, but for now, it's fast enough. |
| 68 ''' | 68 """ |
| 69 try: | 69 try: |
| 70 return max(k[0] for k in self.revmap.iterkeys()) | 70 return max(k[0] for k in self.revmap.iterkeys()) |
| 71 except ValueError: | 71 except ValueError: |
| 72 return 0 | 72 return 0 |
| 73 | 73 |
| 79 """path is the path to the target hg repo. | 79 """path is the path to the target hg repo. |
| 80 | 80 |
| 81 subdir is the subdirectory of the edits *on the svn server*. | 81 subdir is the subdirectory of the edits *on the svn server*. |
| 82 It is needed for stripping paths off in certain cases. | 82 It is needed for stripping paths off in certain cases. |
| 83 """ | 83 """ |
| 84 if repo and repo.ui and not ui_: | |
| 85 ui_ = repo.ui | |
| 84 if not ui_: | 86 if not ui_: |
| 85 ui_ = ui.ui() | 87 ui_ = ui.ui() |
| 86 self.ui = ui_ | 88 self.ui = ui_ |
| 87 if repo: | 89 if repo: |
| 88 self.repo = repo | 90 self.repo = repo |
| 96 self.subdir = subdir | 98 self.subdir = subdir |
| 97 if self.subdir and self.subdir[0] == '/': | 99 if self.subdir and self.subdir[0] == '/': |
| 98 self.subdir = self.subdir[1:] | 100 self.subdir = self.subdir[1:] |
| 99 self.revmap = {} | 101 self.revmap = {} |
| 100 if os.path.exists(self.revmap_file): | 102 if os.path.exists(self.revmap_file): |
| 101 self.revmap = our_util.parse_revmap(self.revmap_file) | 103 self.revmap = util.parse_revmap(self.revmap_file) |
| 102 self.branches = {} | 104 self.branches = {} |
| 103 if os.path.exists(self.branch_info_file): | 105 if os.path.exists(self.branch_info_file): |
| 104 f = open(self.branch_info_file) | 106 f = open(self.branch_info_file) |
| 105 self.branches = pickle.load(f) | 107 self.branches = pickle.load(f) |
| 106 f.close() | 108 f.close() |
| 128 self.readauthors(self.authors_file) | 130 self.readauthors(self.authors_file) |
| 129 if authors and os.path.exists(authors): | 131 if authors and os.path.exists(authors): |
| 130 self.readauthors(authors) | 132 self.readauthors(authors) |
| 131 if self.authors: | 133 if self.authors: |
| 132 self.writeauthors() | 134 self.writeauthors() |
| 135 | |
| 136 self.lastdate = '1970-01-01 00:00:00 -0000' | |
| 133 self.includepaths = {} | 137 self.includepaths = {} |
| 134 self.excludepaths = {} | 138 self.excludepaths = {} |
| 135 if filemap and os.path.exists(filemap): | 139 if filemap and os.path.exists(filemap): |
| 136 self.readfilemap(filemap) | 140 self.readfilemap(filemap) |
| 141 | |
| 142 def fixdate(self, date): | |
| 143 if date is not None: | |
| 144 date = date.replace('T', ' ').replace('Z', '').split('.')[0] | |
| 145 date += ' -0000' | |
| 146 self.lastdate = date | |
| 147 else: | |
| 148 date = self.lastdate | |
| 149 return date | |
| 137 | 150 |
| 138 def __setup_repo(self, repo_path): | 151 def __setup_repo(self, repo_path): |
| 139 """Verify the repo is going to work out for us. | 152 """Verify the repo is going to work out for us. |
| 140 | 153 |
| 141 This method will fail an assertion if the repo exists but doesn't have | 154 This method will fail an assertion if the repo exists but doesn't have |
| 148 assert os.path.isfile(self.uuid_file) | 161 assert os.path.isfile(self.uuid_file) |
| 149 else: | 162 else: |
| 150 self.repo = hg.repository(self.ui, repo_path, create=True) | 163 self.repo = hg.repository(self.ui, repo_path, create=True) |
| 151 os.makedirs(os.path.dirname(self.uuid_file)) | 164 os.makedirs(os.path.dirname(self.uuid_file)) |
| 152 f = open(self.revmap_file, 'w') | 165 f = open(self.revmap_file, 'w') |
| 153 f.write('%s\n' % our_util.REVMAP_FILE_VERSION) | 166 f.write('%s\n' % util.REVMAP_FILE_VERSION) |
| 154 f.flush() | 167 f.flush() |
| 155 f.close() | 168 f.close() |
| 156 | 169 |
| 157 def clear_current_info(self): | 170 def clear_current_info(self): |
| 158 '''Clear the info relevant to a replayed revision so that the next | 171 '''Clear the info relevant to a replayed revision so that the next |
| 204 paths_need_discovery = [p[1] for p in paths_need_discovery] | 217 paths_need_discovery = [p[1] for p in paths_need_discovery] |
| 205 actually_files = [] | 218 actually_files = [] |
| 206 while paths_need_discovery: | 219 while paths_need_discovery: |
| 207 p = paths_need_discovery.pop(0) | 220 p = paths_need_discovery.pop(0) |
| 208 path_could_be_file = True | 221 path_could_be_file = True |
| 209 # TODO(augie) Figure out if you can use break here in a for loop, quick | |
| 210 # testing of that failed earlier. | |
| 211 ind = 0 | 222 ind = 0 |
| 212 while ind < len(paths_need_discovery) and not paths_need_discovery: | 223 while ind < len(paths_need_discovery) and not paths_need_discovery: |
| 213 if op.startswith(p): | 224 if op.startswith(p): |
| 214 path_could_be_file = False | 225 path_could_be_file = False |
| 215 ind += 1 | 226 ind += 1 |
| 231 while filepaths: | 242 while filepaths: |
| 232 path = filepaths.pop(0) | 243 path = filepaths.pop(0) |
| 233 parentdir = '/'.join(path[:-1]) | 244 parentdir = '/'.join(path[:-1]) |
| 234 filepaths = [p for p in filepaths if not '/'.join(p).startswith(parentdir)] | 245 filepaths = [p for p in filepaths if not '/'.join(p).startswith(parentdir)] |
| 235 branchpath = self._normalize_path(parentdir) | 246 branchpath = self._normalize_path(parentdir) |
| 247 if branchpath.startswith('tags/'): | |
| 248 continue | |
| 236 branchname = self._localname(branchpath) | 249 branchname = self._localname(branchpath) |
| 237 if branchpath.startswith('trunk/'): | 250 if branchpath.startswith('trunk/'): |
| 238 branches[self._localname('trunk')] = 'trunk' | 251 branches[self._localname('trunk')] = 'trunk' |
| 239 continue | 252 continue |
| 253 if branchname and branchname.startswith('../'): | |
| 254 continue | |
| 240 branches[branchname] = branchpath | 255 branches[branchname] = branchpath |
| 241 | 256 |
| 242 return branches | 257 return branches |
| 243 | 258 |
| 244 def _path_and_branch_for_path(self, path, existing=True): | 259 def _path_and_branch_for_path(self, path, existing=True): |
| 248 return self._path_and_branch_for_path(path, existing=existing)[1] | 263 return self._path_and_branch_for_path(path, existing=existing)[1] |
| 249 | 264 |
| 250 def _localname(self, path): | 265 def _localname(self, path): |
| 251 """Compute the local name for a branch located at path. | 266 """Compute the local name for a branch located at path. |
| 252 """ | 267 """ |
| 268 assert not path.startswith('tags/') | |
| 253 if path == 'trunk': | 269 if path == 'trunk': |
| 254 return None | 270 return None |
| 255 elif path.startswith('branches/'): | 271 elif path.startswith('branches/'): |
| 256 return path[len('branches/'):] | 272 return path[len('branches/'):] |
| 257 return '../%s' % path | 273 return '../%s' % path |
| 272 If existing=True, will return None, None, None if the file isn't on some known | 288 If existing=True, will return None, None, None if the file isn't on some known |
| 273 branch. If existing=False, then it will guess what the branch would be if it were | 289 branch. If existing=False, then it will guess what the branch would be if it were |
| 274 known. | 290 known. |
| 275 """ | 291 """ |
| 276 path = self._normalize_path(path) | 292 path = self._normalize_path(path) |
| 293 if path.startswith('tags/'): | |
| 294 return None, None, None | |
| 277 test = '' | 295 test = '' |
| 278 path_comps = path.split('/') | 296 path_comps = path.split('/') |
| 279 while self._localname(test) not in self.branches and len(path_comps): | 297 while self._localname(test) not in self.branches and len(path_comps): |
| 280 if not test: | 298 if not test: |
| 281 test = path_comps.pop(0) | 299 test = path_comps.pop(0) |
| 286 if existing: | 304 if existing: |
| 287 return None, None, None | 305 return None, None, None |
| 288 if path.startswith('trunk/'): | 306 if path.startswith('trunk/'): |
| 289 path = test.split('/')[1:] | 307 path = test.split('/')[1:] |
| 290 test = 'trunk' | 308 test = 'trunk' |
| 309 elif path.startswith('branches/'): | |
| 310 elts = path.split('/') | |
| 311 test = '/'.join(elts[:2]) | |
| 312 path = '/'.join(elts[2:]) | |
| 291 else: | 313 else: |
| 292 path = test.split('/')[-1] | 314 path = test.split('/')[-1] |
| 293 test = '/'.join(test.split('/')[:-1]) | 315 test = '/'.join(test.split('/')[:-1]) |
| 294 return path, self._localname(test), test | 316 ln = self._localname(test) |
| 317 if ln and ln.startswith('../'): | |
| 318 return None, None, None | |
| 319 return path, ln, test | |
| 295 | 320 |
| 296 def set_current_rev(self, rev): | 321 def set_current_rev(self, rev): |
| 297 """Set the revision we're currently converting. | 322 """Set the revision we're currently converting. |
| 298 """ | 323 """ |
| 299 self.current_rev = rev | 324 self.current_rev = rev |
| 356 if inc is None or exc is not None: | 381 if inc is None or exc is not None: |
| 357 return False | 382 return False |
| 358 return True | 383 return True |
| 359 | 384 |
| 360 def _is_path_valid(self, path): | 385 def _is_path_valid(self, path): |
| 386 if path is None: | |
| 387 return False | |
| 361 subpath = self._split_branch_path(path)[0] | 388 subpath = self._split_branch_path(path)[0] |
| 362 if subpath is None: | 389 if subpath is None: |
| 363 return False | 390 return False |
| 364 return self._is_file_included(subpath) | 391 return self._is_file_included(subpath) |
| 365 | 392 |
| 502 continue # case 1 | 529 continue # case 1 |
| 503 if paths[p].action == 'D': | 530 if paths[p].action == 'D': |
| 504 # check for case 5 | 531 # check for case 5 |
| 505 for known in self.branches: | 532 for known in self.branches: |
| 506 if self._svnpath(known).startswith(p): | 533 if self._svnpath(known).startswith(p): |
| 507 self.branches_to_delete.add(br) # case 5 | 534 self.branches_to_delete.add(known) # case 5 |
| 508 added_branches.update(self.__determine_parent_branch(p, paths[p].copyfrom_path, | 535 added_branches.update(self.__determine_parent_branch(p, paths[p].copyfrom_path, |
| 509 paths[p].copyfrom_rev, revision.revnum)) | 536 paths[p].copyfrom_rev, revision.revnum)) |
| 510 for t in tags_to_delete: | 537 for t in tags_to_delete: |
| 511 del self.tags[t] | 538 del self.tags[t] |
| 512 for br in self.branches_to_delete: | 539 for br in self.branches_to_delete: |
| 563 # back to a list and sort so we get sane behavior | 590 # back to a list and sort so we get sane behavior |
| 564 files_to_commit = list(files_to_commit) | 591 files_to_commit = list(files_to_commit) |
| 565 files_to_commit.sort() | 592 files_to_commit.sort() |
| 566 branch_batches = {} | 593 branch_batches = {} |
| 567 rev = self.current_rev | 594 rev = self.current_rev |
| 568 date = rev.date.replace('T', ' ').replace('Z', '').split('.')[0] | 595 date = self.fixdate(rev.date) |
| 569 date += ' -0000' | |
| 570 | 596 |
| 571 # build up the branches that have files on them | 597 # build up the branches that have files on them |
| 572 for f in files_to_commit: | 598 for f in files_to_commit: |
| 573 if not self._is_path_valid(f): | 599 if not self._is_path_valid(f): |
| 574 continue | 600 continue |
| 613 | 639 |
| 614 parents = (self.get_parent_revision(rev.revnum, branch), | 640 parents = (self.get_parent_revision(rev.revnum, branch), |
| 615 revlog.nullid) | 641 revlog.nullid) |
| 616 if parents[0] in closed_revs and branch in self.branches_to_delete: | 642 if parents[0] in closed_revs and branch in self.branches_to_delete: |
| 617 continue | 643 continue |
| 618 # TODO this needs to be fixed with the new revmap | 644 extra = util.build_extra(rev.revnum, branch, |
| 619 extra = our_util.build_extra(rev.revnum, branch, | 645 open(self.uuid_file).read(), |
| 620 open(self.uuid_file).read(), | 646 self.subdir) |
| 621 self.subdir) | |
| 622 if branch is not None: | 647 if branch is not None: |
| 623 if (branch not in self.branches | 648 if (branch not in self.branches |
| 624 and branch not in self.repo.branchtags()): | 649 and branch not in self.repo.branchtags()): |
| 625 continue | 650 continue |
| 626 parent_ctx = self.repo.changectx(parents[0]) | 651 parent_ctx = self.repo.changectx(parents[0]) |
| 656 filectxfn, | 681 filectxfn, |
| 657 self.authorforsvnauthor(rev.author), | 682 self.authorforsvnauthor(rev.author), |
| 658 date, | 683 date, |
| 659 extra) | 684 extra) |
| 660 new_hash = self.repo.commitctx(current_ctx) | 685 new_hash = self.repo.commitctx(current_ctx) |
| 661 our_util.describe_commit(self.ui, new_hash, branch) | 686 util.describe_commit(self.ui, new_hash, branch) |
| 662 if (rev.revnum, branch) not in self.revmap: | 687 if (rev.revnum, branch) not in self.revmap: |
| 663 self.add_to_revmap(rev.revnum, branch, new_hash) | 688 self.add_to_revmap(rev.revnum, branch, new_hash) |
| 664 # now we handle branches that need to be committed without any files | 689 # now we handle branches that need to be committed without any files |
| 665 for branch in self.commit_branches_empty: | 690 for branch in self.commit_branches_empty: |
| 666 ha = self.get_parent_revision(rev.revnum, branch) | 691 ha = self.get_parent_revision(rev.revnum, branch) |
| 669 parent_ctx = self.repo.changectx(ha) | 694 parent_ctx = self.repo.changectx(ha) |
| 670 def del_all_files(*args): | 695 def del_all_files(*args): |
| 671 raise IOError | 696 raise IOError |
| 672 # True here meant nuke all files, shouldn't happen with branch closing | 697 # True here meant nuke all files, shouldn't happen with branch closing |
| 673 if self.commit_branches_empty[branch]: #pragma: no cover | 698 if self.commit_branches_empty[branch]: #pragma: no cover |
| 674 raise util.Abort('Empty commit to an open branch attempted. ' | 699 raise hgutil.Abort('Empty commit to an open branch attempted. ' |
| 675 'Please report this issue.') | 700 'Please report this issue.') |
| 676 extra = our_util.build_extra(rev.revnum, branch, | 701 extra = util.build_extra(rev.revnum, branch, |
| 677 open(self.uuid_file).read(), | 702 open(self.uuid_file).read(), |
| 678 self.subdir) | 703 self.subdir) |
| 679 current_ctx = context.memctx(self.repo, | 704 current_ctx = context.memctx(self.repo, |
| 680 (ha, node.nullid), | 705 (ha, node.nullid), |
| 681 rev.message or ' ', | 706 rev.message or ' ', |
| 683 del_all_files, | 708 del_all_files, |
| 684 self.authorforsvnauthor(rev.author), | 709 self.authorforsvnauthor(rev.author), |
| 685 date, | 710 date, |
| 686 extra) | 711 extra) |
| 687 new_hash = self.repo.commitctx(current_ctx) | 712 new_hash = self.repo.commitctx(current_ctx) |
| 688 our_util.describe_commit(self.ui, new_hash, branch) | 713 util.describe_commit(self.ui, new_hash, branch) |
| 689 if (rev.revnum, branch) not in self.revmap: | 714 if (rev.revnum, branch) not in self.revmap: |
| 690 self.add_to_revmap(rev.revnum, branch, new_hash) | 715 self.add_to_revmap(rev.revnum, branch, new_hash) |
| 691 self._save_metadata() | 716 self._save_metadata() |
| 692 self.clear_current_info() | 717 self.clear_current_info() |
| 693 | 718 |
| 694 def authorforsvnauthor(self, author): | 719 def authorforsvnauthor(self, author): |
| 695 if(author in self.authors): | 720 if author in self.authors: |
| 696 return self.authors[author] | 721 return self.authors[author] |
| 697 return '%s%s' %(author, self.author_host) | 722 return '%s%s' % (author, self.author_host) |
| 698 | 723 |
| 699 def svnauthorforauthor(self, author): | 724 def svnauthorforauthor(self, author): |
| 700 for svnauthor, hgauthor in self.authors.iteritems(): | 725 for svnauthor, hgauthor in self.authors.iteritems(): |
| 701 if author == hgauthor: | 726 if author == hgauthor: |
| 702 return svnauthor | 727 return svnauthor |
| 703 else: | 728 else: |
| 704 # Mercurial incorrectly splits at e.g. '.', so we roll our own. | 729 # return the original svn-side author |
| 705 return author.rsplit('@', 1)[0] | 730 return author.rsplit('@', 1)[0] |
| 706 | 731 |
| 707 def readauthors(self, authorfile): | 732 def readauthors(self, authorfile): |
| 708 self.ui.note(('Reading authormap from %s\n') % authorfile) | 733 self.ui.note(('Reading authormap from %s\n') % authorfile) |
| 709 f = open(authorfile, 'r') | 734 f = open(authorfile, 'r') |
| 835 if br_path != '': | 860 if br_path != '': |
| 836 br_path2 = br_path + '/' | 861 br_path2 = br_path + '/' |
| 837 # assuming it is a directory | 862 # assuming it is a directory |
| 838 self.externals[path] = None | 863 self.externals[path] = None |
| 839 map(self.delete_file, [pat for pat in self.current_files.iterkeys() | 864 map(self.delete_file, [pat for pat in self.current_files.iterkeys() |
| 840 if pat.startswith(path)]) | 865 if pat.startswith(path+'/')]) |
| 841 for f in ctx.walk(our_util.PrefixMatch(br_path2)): | 866 for f in ctx.walk(util.PrefixMatch(br_path2)): |
| 842 f_p = '%s/%s' % (path, f[len(br_path2):]) | 867 f_p = '%s/%s' % (path, f[len(br_path2):]) |
| 843 if f_p not in self.current_files: | 868 if f_p not in self.current_files: |
| 844 self.delete_file(f_p) | 869 self.delete_file(f_p) |
| 845 self.delete_file(path) | 870 self.delete_file(path) |
| 846 delete_entry = stash_exception_on_self(delete_entry) | 871 delete_entry = stash_exception_on_self(delete_entry) |
| 847 | 872 |
| 848 def open_file(self, path, parent_baton, base_revision, p=None): | 873 def open_file(self, path, parent_baton, base_revision, p=None): |
| 849 self.current_file = 'foobaz' | 874 self.current_file = None |
| 850 fpath, branch = self._path_and_branch_for_path(path) | 875 fpath, branch = self._path_and_branch_for_path(path) |
| 851 if fpath: | 876 if fpath: |
| 852 self.current_file = path | 877 self.current_file = path |
| 853 self.ui.note('M %s\n' % path) | 878 self.ui.note('M %s\n' % path) |
| 854 if base_revision != -1: | 879 if base_revision != -1: |
| 889 # parentctx is not an ancestor of childctx, files are unrelated | 914 # parentctx is not an ancestor of childctx, files are unrelated |
| 890 return False | 915 return False |
| 891 | 916 |
| 892 def add_file(self, path, parent_baton=None, copyfrom_path=None, | 917 def add_file(self, path, parent_baton=None, copyfrom_path=None, |
| 893 copyfrom_revision=None, file_pool=None): | 918 copyfrom_revision=None, file_pool=None): |
| 894 self.current_file = 'foobaz' | 919 self.current_file = None |
| 895 self.base_revision = None | 920 self.base_revision = None |
| 896 if path in self.deleted_files: | 921 if path in self.deleted_files: |
| 897 del self.deleted_files[path] | 922 del self.deleted_files[path] |
| 898 fpath, branch = self._path_and_branch_for_path(path, existing=False) | 923 fpath, branch = self._path_and_branch_for_path(path, existing=False) |
| 899 if not fpath: | 924 if not fpath: |
| 951 cp_f = '' | 976 cp_f = '' |
| 952 else: | 977 else: |
| 953 source_rev = copyfrom_revision | 978 source_rev = copyfrom_revision |
| 954 cp_f, source_branch = self._path_and_branch_for_path(copyfrom_path) | 979 cp_f, source_branch = self._path_and_branch_for_path(copyfrom_path) |
| 955 if cp_f == '' and br_path == '': | 980 if cp_f == '' and br_path == '': |
| 981 assert br_path is not None | |
| 956 self.branches[branch] = source_branch, source_rev, self.current_rev.revnum | 982 self.branches[branch] = source_branch, source_rev, self.current_rev.revnum |
| 957 new_hash = self.get_parent_revision(source_rev + 1, | 983 new_hash = self.get_parent_revision(source_rev + 1, |
| 958 source_branch) | 984 source_branch) |
| 959 if new_hash == node.nullid: | 985 if new_hash == node.nullid: |
| 960 self.missing_plaintexts.add('%s/' % path) | 986 self.missing_plaintexts.add('%s/' % path) |
| 1034 target = cStringIO.StringIO() | 1060 target = cStringIO.StringIO() |
| 1035 self.stream = target | 1061 self.stream = target |
| 1036 | 1062 |
| 1037 handler, baton = delta.svn_txdelta_apply(source, target, None) | 1063 handler, baton = delta.svn_txdelta_apply(source, target, None) |
| 1038 if not callable(handler): #pragma: no cover | 1064 if not callable(handler): #pragma: no cover |
| 1039 raise util.Abort('Error in Subversion bindings: ' | 1065 raise hgutil.Abort('Error in Subversion bindings: ' |
| 1040 'cannot call handler!') | 1066 'cannot call handler!') |
| 1041 def txdelt_window(window): | 1067 def txdelt_window(window): |
| 1042 try: | 1068 try: |
| 1043 if not self._is_path_valid(self.current_file): | 1069 if not self._is_path_valid(self.current_file): |
| 1044 return | 1070 return |
| 1045 handler(window, baton) | 1071 handler(window, baton) |
| 1048 self.current_files[self.current_file] = target.getvalue() | 1074 self.current_files[self.current_file] = target.getvalue() |
| 1049 except core.SubversionException, e: #pragma: no cover | 1075 except core.SubversionException, e: #pragma: no cover |
| 1050 if e.apr_err == core.SVN_ERR_INCOMPLETE_DATA: | 1076 if e.apr_err == core.SVN_ERR_INCOMPLETE_DATA: |
| 1051 self.missing_plaintexts.add(self.current_file) | 1077 self.missing_plaintexts.add(self.current_file) |
| 1052 else: #pragma: no cover | 1078 else: #pragma: no cover |
| 1053 raise util.Abort(*e.args) | 1079 raise hgutil.Abort(*e.args) |
| 1054 except: #pragma: no cover | 1080 except: #pragma: no cover |
| 1055 print len(base), self.current_file | 1081 print len(base), self.current_file |
| 1056 self._exception_info = sys.exc_info() | 1082 self._exception_info = sys.exc_info() |
| 1057 raise | 1083 raise |
| 1058 return txdelt_window | 1084 return txdelt_window |
