hgext/convert/subversion.py
changeset 6399 5efd447a9b8d
parent 6397 e1402cf5e08a
child 6400 c237b27e1350
equal deleted inserted replaced
6398:0e91ef0b52e7 6399:5efd447a9b8d
   367     def gettags(self):
   367     def gettags(self):
   368         tags = {}
   368         tags = {}
   369         if self.tags is None:
   369         if self.tags is None:
   370             return tags
   370             return tags
   371 
   371 
   372         start = self.revnum(self.head)
   372         # svn tags are just a convention, project branches left in a
   373         try:
   373         # 'tags' directory. There is no other relationship than
   374             for entry in get_log(self.url, [self.tags], self.startrev, start):
   374         # ancestry, which is expensive to discover and makes them hard
   375                 orig_paths, revnum, author, date, message = entry
   375         # to update incrementally.  Worse, past revisions may be
   376                 for path in orig_paths:
   376         # referenced by tags far away in the future, requiring a deep
   377                     if not path.startswith(self.tags+'/'):
   377         # history traversal on every calculation.  Current code
       
   378         # performs a single backward traversal, tracking moves within
       
   379         # the tags directory (tag renaming) and recording a new tag
       
   380         # everytime a project is copied from outside the tags
       
   381         # directory. It also lists deleted tags, this behaviour may
       
   382         # change in the future.
       
   383         pendings = []
       
   384         tagspath = self.tags
       
   385         start = svn.ra.get_latest_revnum(self.ra)
       
   386         try:
       
   387             for entry in get_log(self.url, [self.tags], start, self.startrev):
       
   388                 origpaths, revnum, author, date, message = entry
       
   389                 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p,e 
       
   390                           in origpaths.iteritems() if e.copyfrom_path]
       
   391                 copies.sort()
       
   392                 # Apply moves/copies from more specific to general
       
   393                 copies.reverse()
       
   394 
       
   395                 srctagspath = tagspath
       
   396                 if copies and copies[-1][2] == tagspath:
       
   397                     # Track tags directory moves
       
   398                     srctagspath = copies.pop()[0]
       
   399 
       
   400                 for source, sourcerev, dest in copies:
       
   401                     if not dest.startswith(tagspath + '/'):
   378                         continue
   402                         continue
   379                     ent = orig_paths[path]
   403                     for tag in pendings:
   380                     source = ent.copyfrom_path
   404                         if tag[0].startswith(dest):
   381                     rev = ent.copyfrom_rev
   405                             tagpath = source + tag[0][len(dest):]
   382                     tag = path.split('/')[-1]
   406                             tag[:2] = [tagpath, sourcerev]
   383                     tags[tag] = self.revid(rev, module=source)
   407                             break
       
   408                     else:
       
   409                         pendings.append([source, sourcerev, dest.split('/')[-1]])
       
   410 
       
   411                 # Tell tag renamings from tag creations
       
   412                 remainings = []
       
   413                 for source, sourcerev, tagname in pendings:
       
   414                     if source.startswith(srctagspath):
       
   415                         remainings.append([source, sourcerev, tagname])
       
   416                         continue
       
   417                     # From revision may be fake, get one with changes
       
   418                     tagid = self.latest(source, sourcerev)
       
   419                     if tagid:
       
   420                         tags[tagname] = tagid
       
   421                 pendings = remainings
       
   422                 tagspath = srctagspath
       
   423 
   384         except SubversionException, (inst, num):
   424         except SubversionException, (inst, num):
   385             self.ui.note('no tags found at revision %d\n' % start)
   425             self.ui.note('no tags found at revision %d\n' % start)
   386         return tags
   426         return tags
   387 
   427 
   388     def converted(self, rev, destrev):
   428     def converted(self, rev, destrev):