hgext/convert/subversion.py
branchstable
changeset 11195 46bb49134498
parent 11194 6798536454e6
child 11196 573bef78763f
equal deleted inserted replaced
11194:6798536454e6 11195:46bb49134498
   446         # directory. It also lists deleted tags, this behaviour may
   446         # directory. It also lists deleted tags, this behaviour may
   447         # change in the future.
   447         # change in the future.
   448         pendings = []
   448         pendings = []
   449         tagspath = self.tags
   449         tagspath = self.tags
   450         start = svn.ra.get_latest_revnum(self.ra)
   450         start = svn.ra.get_latest_revnum(self.ra)
   451         for entry in self._getlog([self.tags], start, self.startrev):
   451         stream = self._getlog([self.tags], start, self.startrev)
   452             origpaths, revnum, author, date, message = entry
   452         try:
   453             copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
   453             for entry in stream:
   454                       in origpaths.iteritems() if e.copyfrom_path]
   454                 origpaths, revnum, author, date, message = entry
   455             # Apply moves/copies from more specific to general
   455                 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
   456             copies.sort(reverse=True)
   456                           in origpaths.iteritems() if e.copyfrom_path]
   457 
   457                 # Apply moves/copies from more specific to general
   458             srctagspath = tagspath
   458                 copies.sort(reverse=True)
   459             if copies and copies[-1][2] == tagspath:
   459 
   460                 # Track tags directory moves
   460                 srctagspath = tagspath
   461                 srctagspath = copies.pop()[0]
   461                 if copies and copies[-1][2] == tagspath:
   462 
   462                     # Track tags directory moves
   463             for source, sourcerev, dest in copies:
   463                     srctagspath = copies.pop()[0]
   464                 if not dest.startswith(tagspath + '/'):
   464 
   465                     continue
   465                 for source, sourcerev, dest in copies:
   466                 for tag in pendings:
   466                     if not dest.startswith(tagspath + '/'):
   467                     if tag[0].startswith(dest):
   467                         continue
   468                         tagpath = source + tag[0][len(dest):]
   468                     for tag in pendings:
   469                         tag[:2] = [tagpath, sourcerev]
   469                         if tag[0].startswith(dest):
       
   470                             tagpath = source + tag[0][len(dest):]
       
   471                             tag[:2] = [tagpath, sourcerev]
       
   472                             break
       
   473                     else:
       
   474                         pendings.append([source, sourcerev, dest])
       
   475 
       
   476                 # Filter out tags with children coming from different
       
   477                 # parts of the repository like:
       
   478                 # /tags/tag.1 (from /trunk:10)
       
   479                 # /tags/tag.1/foo (from /branches/foo:12)
       
   480                 # Here/tags/tag.1 discarded as well as its children.
       
   481                 # It happens with tools like cvs2svn. Such tags cannot
       
   482                 # be represented in mercurial.
       
   483                 addeds = dict((p, e.copyfrom_path) for p, e
       
   484                               in origpaths.iteritems()
       
   485                               if e.action == 'A' and e.copyfrom_path)
       
   486                 badroots = set()
       
   487                 for destroot in addeds:
       
   488                     for source, sourcerev, dest in pendings:
       
   489                         if (not dest.startswith(destroot + '/')
       
   490                             or source.startswith(addeds[destroot] + '/')):
       
   491                             continue
       
   492                         badroots.add(destroot)
   470                         break
   493                         break
   471                 else:
   494 
   472                     pendings.append([source, sourcerev, dest])
   495                 for badroot in badroots:
   473 
   496                     pendings = [p for p in pendings if p[2] != badroot
   474             # Filter out tags with children coming from different
   497                                 and not p[2].startswith(badroot + '/')]
   475             # parts of the repository like:
   498 
   476             # /tags/tag.1 (from /trunk:10)
   499                 # Tell tag renamings from tag creations
   477             # /tags/tag.1/foo (from /branches/foo:12)
   500                 remainings = []
   478             # Here/tags/tag.1 discarded as well as its children.
       
   479             # It happens with tools like cvs2svn. Such tags cannot
       
   480             # be represented in mercurial.
       
   481             addeds = dict((p, e.copyfrom_path) for p, e
       
   482                           in origpaths.iteritems()
       
   483                           if e.action == 'A' and e.copyfrom_path)
       
   484             badroots = set()
       
   485             for destroot in addeds:
       
   486                 for source, sourcerev, dest in pendings:
   501                 for source, sourcerev, dest in pendings:
   487                     if (not dest.startswith(destroot + '/')
   502                     tagname = dest.split('/')[-1]
   488                         or source.startswith(addeds[destroot] + '/')):
   503                     if source.startswith(srctagspath):
       
   504                         remainings.append([source, sourcerev, tagname])
   489                         continue
   505                         continue
   490                     badroots.add(destroot)
   506                     if tagname in tags:
   491                     break
   507                         # Keep the latest tag value
   492 
   508                         continue
   493             for badroot in badroots:
   509                     # From revision may be fake, get one with changes
   494                 pendings = [p for p in pendings if p[2] != badroot
   510                     try:
   495                             and not p[2].startswith(badroot + '/')]
   511                         tagid = self.latest(source, sourcerev)
   496 
   512                         if tagid and tagname not in tags:
   497             # Tell tag renamings from tag creations
   513                             tags[tagname] = tagid
   498             remainings = []
   514                     except SvnPathNotFound:
   499             for source, sourcerev, dest in pendings:
   515                         # It happens when we are following directories
   500                 tagname = dest.split('/')[-1]
   516                         # we assumed were copied with their parents
   501                 if source.startswith(srctagspath):
   517                         # but were really created in the tag
   502                     remainings.append([source, sourcerev, tagname])
   518                         # directory.
   503                     continue
   519                         pass
   504                 if tagname in tags:
   520                 pendings = remainings
   505                     # Keep the latest tag value
   521                 tagspath = srctagspath
   506                     continue
   522         finally:
   507                 # From revision may be fake, get one with changes
   523             stream.close()
   508                 try:
       
   509                     tagid = self.latest(source, sourcerev)
       
   510                     if tagid and tagname not in tags:
       
   511                         tags[tagname] = tagid
       
   512                 except SvnPathNotFound:
       
   513                     # It happens when we are following directories
       
   514                     # we assumed were copied with their parents
       
   515                     # but were really created in the tag
       
   516                     # directory.
       
   517                     pass
       
   518             pendings = remainings
       
   519             tagspath = srctagspath
       
   520 
       
   521         return tags
   524         return tags
   522 
   525 
   523     def converted(self, rev, destrev):
   526     def converted(self, rev, destrev):
   524         if not self.wc:
   527         if not self.wc:
   525             return
   528             return