hgext/convert/subversion.py
changeset 4825 a265fe42abe7
parent 4824 e20e40f67f0e
child 4835 5e365008360f
equal deleted inserted replaced
4824:e20e40f67f0e 4825:a265fe42abe7
    76             pass
    76             pass
    77 
    77 
    78         self.last_changed = self.latest(self.module, latest)
    78         self.last_changed = self.latest(self.module, latest)
    79 
    79 
    80         self.head = self.revid(self.last_changed)
    80         self.head = self.revid(self.last_changed)
       
    81 
       
    82     def setrevmap(self, revmap):
       
    83         lastrevs = {}
       
    84         for revid in revmap.keys():
       
    85             uuid, module, revnum = self.revsplit(revid)
       
    86             lastrevnum = lastrevs.setdefault(module, revnum)
       
    87             if revnum > lastrevnum:
       
    88                 lastrevs[module] = revnum
       
    89         self.lastrevs = lastrevs
       
    90 
       
    91     def getheads(self):
       
    92         # detect standard /branches, /tags, /trunk layout
       
    93         optrev = svn.core.svn_opt_revision_t()
       
    94         optrev.kind = svn.core.svn_opt_revision_number
       
    95         optrev.value.number = self.last_changed
       
    96         rpath = self.url.strip('/')
       
    97         paths = svn.client.ls(rpath, optrev, False, self.ctx)
       
    98         if 'branches' in paths and 'trunk' in paths:
       
    99             self.module += '/trunk'
       
   100             lt = self.latest(self.module, self.last_changed)
       
   101             self.head = self.revid(lt)
       
   102             self.heads = [self.head]
       
   103             branches = svn.client.ls(rpath + '/branches', optrev, False, self.ctx)
       
   104             for branch in branches.keys():
       
   105                 module = '/branches/' + branch
       
   106                 brevnum = self.latest(module, self.last_changed)
       
   107                 brev = self.revid(brevnum, module)
       
   108                 self.ui.note('found branch %s at %d\n' % (branch, brevnum))
       
   109                 self.heads.append(brev)
       
   110         else:
       
   111             self.heads = [self.head]
       
   112         return self.heads
       
   113 
       
   114     def getfile(self, file, rev):
       
   115         data, mode = self._getfile(file, rev)
       
   116         self.modecache[(file, rev)] = mode
       
   117         return data
       
   118 
       
   119     def getmode(self, file, rev):        
       
   120         return self.modecache[(file, rev)]
       
   121 
       
   122     def getchanges(self, rev):
       
   123         self.modecache = {}
       
   124         files = self.files[rev]
       
   125         cl = files
       
   126         cl.sort()
       
   127         # caller caches the result, so free it here to release memory
       
   128         del self.files[rev]
       
   129         return cl
       
   130 
       
   131     def getcommit(self, rev):
       
   132         if rev not in self.commits:
       
   133             uuid, module, revnum = self.revsplit(rev)
       
   134             self.module = module
       
   135             self.reparent(module)
       
   136             stop = self.lastrevs.get(module, 0)
       
   137             self._fetch_revisions(from_revnum=revnum, to_revnum=stop)
       
   138         commit = self.commits[rev]
       
   139         # caller caches the result, so free it here to release memory
       
   140         del self.commits[rev]
       
   141         return commit
       
   142 
       
   143     def gettags(self):
       
   144         tags = {}
       
   145         def parselogentry(*arg, **args):
       
   146             orig_paths, revnum, author, date, message, pool = arg
       
   147             for path in orig_paths:
       
   148                 if not path.startswith('/tags/'):
       
   149                     continue
       
   150                 ent = orig_paths[path]
       
   151                 source = ent.copyfrom_path
       
   152                 rev = ent.copyfrom_rev
       
   153                 tag = path.split('/', 2)[2]
       
   154                 tags[tag] = self.revid(rev, module=source)
       
   155 
       
   156         start = self.revnum(self.head)
       
   157         try:
       
   158             svn.ra.get_log(self.ra, ['/tags'], 0, start, 0, True, False,
       
   159                            parselogentry)
       
   160             return tags
       
   161         except SubversionException:
       
   162             self.ui.note('no tags found at revision %d\n' % start)
       
   163             return {}
       
   164 
       
   165     # -- helper functions --
    81 
   166 
    82     def revid(self, revnum, module=None):
   167     def revid(self, revnum, module=None):
    83         if not module:
   168         if not module:
    84             module = self.module
   169             module = self.module
    85         return (u"svn:%s%s@%s" % (self.uuid, module, revnum)).decode(self.encoding)
   170         return (u"svn:%s%s@%s" % (self.uuid, module, revnum)).decode(self.encoding)
   419             if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
   504             if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
   420                 raise NoSuchRevision(branch=self, 
   505                 raise NoSuchRevision(branch=self, 
   421                     revision="Revision number %d" % to_revnum)
   506                     revision="Revision number %d" % to_revnum)
   422             raise
   507             raise
   423 
   508 
   424     def setrevmap(self, revmap):
       
   425         lastrevs = {}
       
   426         for revid in revmap.keys():
       
   427             uuid, module, revnum = self.revsplit(revid)
       
   428             lastrevnum = lastrevs.setdefault(module, revnum)
       
   429             if revnum > lastrevnum:
       
   430                 lastrevs[module] = revnum
       
   431         self.lastrevs = lastrevs
       
   432 
       
   433     def getheads(self):
       
   434         # detect standard /branches, /tags, /trunk layout
       
   435         optrev = svn.core.svn_opt_revision_t()
       
   436         optrev.kind = svn.core.svn_opt_revision_number
       
   437         optrev.value.number = self.last_changed
       
   438         rpath = self.url.strip('/')
       
   439         paths = svn.client.ls(rpath, optrev, False, self.ctx)
       
   440         if 'branches' in paths and 'trunk' in paths:
       
   441             self.module += '/trunk'
       
   442             lt = self.latest(self.module, self.last_changed)
       
   443             self.head = self.revid(lt)
       
   444             self.heads = [self.head]
       
   445             branches = svn.client.ls(rpath + '/branches', optrev, False, self.ctx)
       
   446             for branch in branches.keys():
       
   447                 module = '/branches/' + branch
       
   448                 brevnum = self.latest(module, self.last_changed)
       
   449                 brev = self.revid(brevnum, module)
       
   450                 self.ui.note('found branch %s at %d\n' % (branch, brevnum))
       
   451                 self.heads.append(brev)
       
   452         else:
       
   453             self.heads = [self.head]
       
   454         return self.heads
       
   455 
       
   456     def _getfile(self, file, rev):
   509     def _getfile(self, file, rev):
   457         io = StringIO()
   510         io = StringIO()
   458         # TODO: ra.get_file transmits the whole file instead of diffs.
   511         # TODO: ra.get_file transmits the whole file instead of diffs.
   459         mode = ''
   512         mode = ''
   460         try:
   513         try:
   477         if mode == 'l':
   530         if mode == 'l':
   478             link_prefix = "link "
   531             link_prefix = "link "
   479             if data.startswith(link_prefix):
   532             if data.startswith(link_prefix):
   480                 data = data[len(link_prefix):]
   533                 data = data[len(link_prefix):]
   481         return data, mode
   534         return data, mode
   482 
       
   483     def getfile(self, file, rev):
       
   484         data, mode = self._getfile(file, rev)
       
   485         self.modecache[(file, rev)] = mode
       
   486         return data
       
   487 
       
   488     def getmode(self, file, rev):        
       
   489         return self.modecache[(file, rev)]
       
   490 
       
   491     def getchanges(self, rev):
       
   492         self.modecache = {}
       
   493         files = self.files[rev]
       
   494         cl = files
       
   495         cl.sort()
       
   496         # caller caches the result, so free it here to release memory
       
   497         del self.files[rev]
       
   498         return cl
       
   499 
       
   500     def getcommit(self, rev):
       
   501         if rev not in self.commits:
       
   502             uuid, module, revnum = self.revsplit(rev)
       
   503             self.module = module
       
   504             self.reparent(module)
       
   505             stop = self.lastrevs.get(module, 0)
       
   506             self._fetch_revisions(from_revnum=revnum, to_revnum=stop)
       
   507         commit = self.commits[rev]
       
   508         # caller caches the result, so free it here to release memory
       
   509         del self.commits[rev]
       
   510         return commit
       
   511 
       
   512     def gettags(self):
       
   513         tags = {}
       
   514         def parselogentry(*arg, **args):
       
   515             orig_paths, revnum, author, date, message, pool = arg
       
   516             for path in orig_paths:
       
   517                 if not path.startswith('/tags/'):
       
   518                     continue
       
   519                 ent = orig_paths[path]
       
   520                 source = ent.copyfrom_path
       
   521                 rev = ent.copyfrom_rev
       
   522                 tag = path.split('/', 2)[2]
       
   523                 tags[tag] = self.revid(rev, module=source)
       
   524 
       
   525         start = self.revnum(self.head)
       
   526         try:
       
   527             svn.ra.get_log(self.ra, ['/tags'], 0, start, 0, True, False,
       
   528                            parselogentry)
       
   529             return tags
       
   530         except SubversionException:
       
   531             self.ui.note('no tags found at revision %d\n' % start)
       
   532             return {}
       
   533 
   535 
   534     def _find_children(self, path, revnum):
   536     def _find_children(self, path, revnum):
   535         path = path.strip("/")
   537         path = path.strip("/")
   536 
   538 
   537         def _find_children_fallback(path, revnum):
   539         def _find_children_fallback(path, revnum):