hgext/convert/subversion.py
branchstable
changeset 15599 c6be93a4c378
parent 15381 c519cd8f0169
child 15605 2ad5b8937d0d
child 15750 03d04296cfab
equal deleted inserted replaced
15598:a77ce45584ef 15599:c6be93a4c378
    48     mod = ''
    48     mod = ''
    49     if len(parts) > 1:
    49     if len(parts) > 1:
    50         mod = '/' + parts[1]
    50         mod = '/' + parts[1]
    51     return parts[0][4:], mod, int(revnum)
    51     return parts[0][4:], mod, int(revnum)
    52 
    52 
       
    53 def quote(s):
       
    54     # As of svn 1.7, many svn calls expect "canonical" paths. In
       
    55     # theory, we should call svn.core.*canonicalize() on all paths
       
    56     # before passing them to the API.  Instead, we assume the base url
       
    57     # is canonical and copy the behaviour of svn URL encoding function
       
    58     # so we can extend it safely with new components. The "safe"
       
    59     # characters were taken from the "svn_uri__char_validity" table in
       
    60     # libsvn_subr/path.c.
       
    61     return urllib.quote(s, "!$&'()*+,-./:=@_~")
       
    62 
    53 def geturl(path):
    63 def geturl(path):
    54     try:
    64     try:
    55         return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
    65         return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
    56     except SubversionException:
    66     except SubversionException:
       
    67         # svn.client.url_from_path() fails with local repositories
    57         pass
    68         pass
    58     if os.path.isdir(path):
    69     if os.path.isdir(path):
    59         path = os.path.normpath(os.path.abspath(path))
    70         path = os.path.normpath(os.path.abspath(path))
    60         if os.name == 'nt':
    71         if os.name == 'nt':
    61             path = '/' + util.normpath(path)
    72             path = '/' + util.normpath(path)
    62         # Module URL is later compared with the repository URL returned
    73         # Module URL is later compared with the repository URL returned
    63         # by svn API, which is UTF-8.
    74         # by svn API, which is UTF-8.
    64         path = encoding.tolocal(path)
    75         path = encoding.tolocal(path)
    65         return 'file://%s' % urllib.quote(path)
    76         path = 'file://%s' % quote(path)
    66     return path
    77     return svn.core.svn_path_canonicalize(path)
    67 
    78 
    68 def optrev(number):
    79 def optrev(number):
    69     optrev = svn.core.svn_opt_revision_t()
    80     optrev = svn.core.svn_opt_revision_t()
    70     optrev.kind = svn.core.svn_opt_revision_number
    81     optrev.kind = svn.core.svn_opt_revision_number
    71     optrev.value.number = number
    82     optrev.value.number = number
   304                 lastrevs[module] = revnum
   315                 lastrevs[module] = revnum
   305         self.lastrevs = lastrevs
   316         self.lastrevs = lastrevs
   306 
   317 
   307     def exists(self, path, optrev):
   318     def exists(self, path, optrev):
   308         try:
   319         try:
   309             svn.client.ls(self.url.rstrip('/') + '/' + urllib.quote(path),
   320             svn.client.ls(self.url.rstrip('/') + '/' + quote(path),
   310                                  optrev, False, self.ctx)
   321                                  optrev, False, self.ctx)
   311             return True
   322             return True
   312         except SubversionException:
   323         except SubversionException:
   313             return False
   324             return False
   314 
   325 
   356             self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
   367             self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
   357 
   368 
   358         # Check if branches bring a few more heads to the list
   369         # Check if branches bring a few more heads to the list
   359         if branches:
   370         if branches:
   360             rpath = self.url.strip('/')
   371             rpath = self.url.strip('/')
   361             branchnames = svn.client.ls(rpath + '/' + urllib.quote(branches),
   372             branchnames = svn.client.ls(rpath + '/' + quote(branches),
   362                                         rev, False, self.ctx)
   373                                         rev, False, self.ctx)
   363             for branch in branchnames.keys():
   374             for branch in branchnames.keys():
   364                 module = '%s/%s/%s' % (oldmodule, branches, branch)
   375                 module = '%s/%s/%s' % (oldmodule, branches, branch)
   365                 if not isdir(module, self.last_changed):
   376                 if not isdir(module, self.last_changed):
   366                     continue
   377                     continue
   392         if parents:
   403         if parents:
   393             files, self.removed, copies = self.expandpaths(rev, paths, parents)
   404             files, self.removed, copies = self.expandpaths(rev, paths, parents)
   394         else:
   405         else:
   395             # Perform a full checkout on roots
   406             # Perform a full checkout on roots
   396             uuid, module, revnum = revsplit(rev)
   407             uuid, module, revnum = revsplit(rev)
   397             entries = svn.client.ls(self.baseurl + urllib.quote(module),
   408             entries = svn.client.ls(self.baseurl + quote(module),
   398                                     optrev(revnum), True, self.ctx)
   409                                     optrev(revnum), True, self.ctx)
   399             files = [n for n, e in entries.iteritems()
   410             files = [n for n, e in entries.iteritems()
   400                      if e.kind == svn.core.svn_node_file]
   411                      if e.kind == svn.core.svn_node_file]
   401             copies = {}
   412             copies = {}
   402             self.removed = set()
   413             self.removed = set()
   593 
   604 
   594     def reparent(self, module):
   605     def reparent(self, module):
   595         """Reparent the svn transport and return the previous parent."""
   606         """Reparent the svn transport and return the previous parent."""
   596         if self.prevmodule == module:
   607         if self.prevmodule == module:
   597             return module
   608             return module
   598         svnurl = self.baseurl + urllib.quote(module)
   609         svnurl = self.baseurl + quote(module)
   599         prevmodule = self.prevmodule
   610         prevmodule = self.prevmodule
   600         if prevmodule is None:
   611         if prevmodule is None:
   601             prevmodule = ''
   612             prevmodule = ''
   602         self.ui.debug("reparent to %s\n" % svnurl)
   613         self.ui.debug("reparent to %s\n" % svnurl)
   603         svn.ra.reparent(self.ra, svnurl)
   614         svn.ra.reparent(self.ra, svnurl)
   864 
   875 
   865     def _iterfiles(self, path, revnum):
   876     def _iterfiles(self, path, revnum):
   866         """Enumerate all files in path at revnum, recursively."""
   877         """Enumerate all files in path at revnum, recursively."""
   867         path = path.strip('/')
   878         path = path.strip('/')
   868         pool = Pool()
   879         pool = Pool()
   869         rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/')
   880         rpath = '/'.join([self.baseurl, quote(path)]).strip('/')
   870         entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool)
   881         entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool)
   871         if path:
   882         if path:
   872             path += '/'
   883             path += '/'
   873         return ((path + p) for p, e in entries.iteritems()
   884         return ((path + p) for p, e in entries.iteritems()
   874                 if e.kind == svn.core.svn_node_file)
   885                 if e.kind == svn.core.svn_node_file)