Mercurial > hg
comparison hgext/convert/subversion.py @ 5957:971a17af5982
convert: prevent svn branches to leave the root module tree
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Sat, 26 Jan 2008 14:45:04 +0100 |
parents | 094638b3cbed |
children | 59dce24933ad |
comparison
equal
deleted
inserted
replaced
5956:094638b3cbed | 5957:971a17af5982 |
---|---|
180 self.transport = transport.SvnRaTransport(url=self.url) | 180 self.transport = transport.SvnRaTransport(url=self.url) |
181 self.ra = self.transport.ra | 181 self.ra = self.transport.ra |
182 self.ctx = self.transport.client | 182 self.ctx = self.transport.client |
183 self.base = svn.ra.get_repos_root(self.ra) | 183 self.base = svn.ra.get_repos_root(self.ra) |
184 self.module = self.url[len(self.base):] | 184 self.module = self.url[len(self.base):] |
185 self.rootmodule = self.module | |
185 self.commits = {} | 186 self.commits = {} |
186 self.paths = {} | 187 self.paths = {} |
187 self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding) | 188 self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding) |
188 except SubversionException, e: | 189 except SubversionException, e: |
189 ui.print_exc() | 190 ui.print_exc() |
199 self.get_blacklist() | 200 self.get_blacklist() |
200 except IOError, e: | 201 except IOError, e: |
201 pass | 202 pass |
202 | 203 |
203 self.head = self.latest(self.module, latest) | 204 self.head = self.latest(self.module, latest) |
205 if not self.head: | |
206 raise util.Abort(_('no revision found in module %s') % | |
207 self.module.encode(self.encoding)) | |
204 self.last_changed = self.revnum(self.head) | 208 self.last_changed = self.revnum(self.head) |
205 | 209 |
206 self._changescache = None | 210 self._changescache = None |
207 | 211 |
208 if os.path.exists(os.path.join(url, '.svn/entries')): | 212 if os.path.exists(os.path.join(url, '.svn/entries')): |
251 # from them. We keep the project root otherwise. | 255 # from them. We keep the project root otherwise. |
252 if trunk: | 256 if trunk: |
253 oldmodule = self.module or '' | 257 oldmodule = self.module or '' |
254 self.module += '/' + trunk | 258 self.module += '/' + trunk |
255 self.head = self.latest(self.module, self.last_changed) | 259 self.head = self.latest(self.module, self.last_changed) |
260 if not self.head: | |
261 raise util.Abort(_('no revision found in module %s') % | |
262 self.module.encode(self.encoding)) | |
256 | 263 |
257 # First head in the list is the module's head | 264 # First head in the list is the module's head |
258 self.heads = [self.head] | 265 self.heads = [self.head] |
259 self.tags = '%s/%s' % (oldmodule , (tags or 'tags')) | 266 self.tags = '%s/%s' % (oldmodule , (tags or 'tags')) |
260 | 267 |
264 branchnames = svn.client.ls(rpath + '/' + branches, rev, False, | 271 branchnames = svn.client.ls(rpath + '/' + branches, rev, False, |
265 self.ctx) | 272 self.ctx) |
266 for branch in branchnames.keys(): | 273 for branch in branchnames.keys(): |
267 module = '%s/%s/%s' % (oldmodule, branches, branch) | 274 module = '%s/%s/%s' % (oldmodule, branches, branch) |
268 brevid = self.latest(module, self.last_changed) | 275 brevid = self.latest(module, self.last_changed) |
276 if not brevid: | |
277 self.ui.note(_('ignoring empty branch %s\n') % | |
278 branch.encode(self.encoding)) | |
279 continue | |
269 self.ui.note('found branch %s at %d\n' % | 280 self.ui.note('found branch %s at %d\n' % |
270 (branch, self.revnum(brevid))) | 281 (branch, self.revnum(brevid))) |
271 self.heads.append(brevid) | 282 self.heads.append(brevid) |
272 | 283 |
273 return self.heads | 284 return self.heads |
378 return uuid, mod, revnum | 389 return uuid, mod, revnum |
379 | 390 |
380 def latest(self, path, stop=0): | 391 def latest(self, path, stop=0): |
381 """Find the latest revid affecting path, up to stop. It may return | 392 """Find the latest revid affecting path, up to stop. It may return |
382 a revision in a different module, since a branch may be moved without | 393 a revision in a different module, since a branch may be moved without |
383 a change being reported. | 394 a change being reported. Return None if computed module does not |
395 belong to rootmodule subtree. | |
384 """ | 396 """ |
385 if not stop: | 397 if not stop: |
386 stop = svn.ra.get_latest_revnum(self.ra) | 398 stop = svn.ra.get_latest_revnum(self.ra) |
387 try: | 399 try: |
388 self.reparent('') | 400 self.reparent('') |
412 path = newpath | 424 path = newpath |
413 break | 425 break |
414 finally: | 426 finally: |
415 stream.close() | 427 stream.close() |
416 | 428 |
429 if not path.startswith(self.rootmodule): | |
430 self.ui.debug(_('ignoring foreign branch %r\n') % path) | |
431 return None | |
417 return self.revid(dirent.created_rev, path) | 432 return self.revid(dirent.created_rev, path) |
418 | 433 |
419 def get_blacklist(self): | 434 def get_blacklist(self): |
420 """Avoid certain revision numbers. | 435 """Avoid certain revision numbers. |
421 It is not uncommon for two nearby revisions to cancel each other | 436 It is not uncommon for two nearby revisions to cancel each other |
643 the revision is a branch root. | 658 the revision is a branch root. |
644 """ | 659 """ |
645 self.ui.debug("parsing revision %d (%d changes)\n" % | 660 self.ui.debug("parsing revision %d (%d changes)\n" % |
646 (revnum, len(orig_paths))) | 661 (revnum, len(orig_paths))) |
647 | 662 |
663 branched = False | |
648 rev = self.revid(revnum) | 664 rev = self.revid(revnum) |
649 # branch log might return entries for a parent we already have | 665 # branch log might return entries for a parent we already have |
650 | 666 |
651 if (rev in self.commits or revnum < to_revnum): | 667 if (rev in self.commits or revnum < to_revnum): |
652 return None, False | 668 return None, branched |
653 | 669 |
654 parents = [] | 670 parents = [] |
655 # check whether this revision is the start of a branch | 671 # check whether this revision is the start of a branch |
656 if self.module in orig_paths: | 672 if self.module in orig_paths: |
657 ent = orig_paths[self.module] | 673 ent = orig_paths[self.module] |
658 if ent.copyfrom_path: | 674 if ent.copyfrom_path: |
675 branched = True | |
659 # ent.copyfrom_rev may not be the actual last revision | 676 # ent.copyfrom_rev may not be the actual last revision |
660 previd = self.latest(ent.copyfrom_path, ent.copyfrom_rev) | 677 previd = self.latest(ent.copyfrom_path, ent.copyfrom_rev) |
661 parents = [previd] | 678 if previd is not None: |
662 prevmodule, prevnum = self.revsplit(previd)[1:] | 679 parents = [previd] |
663 self.ui.note('found parent of branch %s at %d: %s\n' % | 680 prevmodule, prevnum = self.revsplit(previd)[1:] |
664 (self.module, prevnum, prevmodule)) | 681 self.ui.note('found parent of branch %s at %d: %s\n' % |
682 (self.module, prevnum, prevmodule)) | |
665 else: | 683 else: |
666 self.ui.debug("No copyfrom path, don't know what to do.\n") | 684 self.ui.debug("No copyfrom path, don't know what to do.\n") |
667 | 685 |
668 orig_paths = orig_paths.items() | 686 orig_paths = orig_paths.items() |
669 orig_paths.sort() | 687 orig_paths.sort() |
701 # commit object. Both will be updated below. | 719 # commit object. Both will be updated below. |
702 self.paths[rev] = (paths, cset.parents) | 720 self.paths[rev] = (paths, cset.parents) |
703 if self.child_cset and not self.child_cset.parents: | 721 if self.child_cset and not self.child_cset.parents: |
704 self.child_cset.parents[:] = [rev] | 722 self.child_cset.parents[:] = [rev] |
705 self.child_cset = cset | 723 self.child_cset = cset |
706 return cset, len(parents) > 0 | 724 return cset, branched |
707 | 725 |
708 self.ui.note('fetching revision log for "%s" from %d to %d\n' % | 726 self.ui.note('fetching revision log for "%s" from %d to %d\n' % |
709 (self.module, from_revnum, to_revnum)) | 727 (self.module, from_revnum, to_revnum)) |
710 | 728 |
711 try: | 729 try: |
712 firstcset = None | 730 firstcset = None |
731 branched = False | |
713 stream = get_log(self.url, [self.module], from_revnum, to_revnum) | 732 stream = get_log(self.url, [self.module], from_revnum, to_revnum) |
714 try: | 733 try: |
715 for entry in stream: | 734 for entry in stream: |
716 paths, revnum, author, date, message = entry | 735 paths, revnum, author, date, message = entry |
717 if self.is_blacklisted(revnum): | 736 if self.is_blacklisted(revnum): |
728 if branched: | 747 if branched: |
729 break | 748 break |
730 finally: | 749 finally: |
731 stream.close() | 750 stream.close() |
732 | 751 |
733 if firstcset and not firstcset.parents: | 752 if not branched and firstcset and not firstcset.parents: |
734 # The first revision of the sequence (the last fetched one) | 753 # The first revision of the sequence (the last fetched one) |
735 # has invalid parents if not a branch root. Find the parent | 754 # has invalid parents if not a branch root. Find the parent |
736 # revision now, if any. | 755 # revision now, if any. |
737 try: | 756 try: |
738 firstrevnum = self.revnum(firstcset.rev) | 757 firstrevnum = self.revnum(firstcset.rev) |
739 if firstrevnum > 1: | 758 if firstrevnum > 1: |
740 latest = self.latest(self.module, firstrevnum - 1) | 759 latest = self.latest(self.module, firstrevnum - 1) |
741 firstcset.parents.append(latest) | 760 if latest: |
761 firstcset.parents.append(latest) | |
742 except util.Abort: | 762 except util.Abort: |
743 pass | 763 pass |
744 except SubversionException, (inst, num): | 764 except SubversionException, (inst, num): |
745 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION: | 765 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION: |
746 raise NoSuchRevision(branch=self, | 766 raise NoSuchRevision(branch=self, |