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,