Mercurial > hg
diff hgext/convert/subversion.py @ 15599:c6be93a4c378 stable
convert/svn: fix URL quoting issue with svn 1.7
As of svn 1.7, many svn calls expect "canonical" paths. In theory, we should
call svn.core.*canonicalize() on all paths before passing them to the API.
Instead, we assume the base url is canonical and copy the behaviour of svn URL
encoding function so we can extend it safely with new components.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Thu, 01 Dec 2011 20:42:24 +0100 |
parents | c519cd8f0169 |
children | 2ad5b8937d0d 03d04296cfab |
line wrap: on
line diff
--- a/hgext/convert/subversion.py Wed Nov 30 15:11:00 2011 +0100 +++ b/hgext/convert/subversion.py Thu Dec 01 20:42:24 2011 +0100 @@ -50,10 +50,21 @@ mod = '/' + parts[1] return parts[0][4:], mod, int(revnum) +def quote(s): + # As of svn 1.7, many svn calls expect "canonical" paths. In + # theory, we should call svn.core.*canonicalize() on all paths + # before passing them to the API. Instead, we assume the base url + # is canonical and copy the behaviour of svn URL encoding function + # so we can extend it safely with new components. The "safe" + # characters were taken from the "svn_uri__char_validity" table in + # libsvn_subr/path.c. + return urllib.quote(s, "!$&'()*+,-./:=@_~") + def geturl(path): try: return svn.client.url_from_path(svn.core.svn_path_canonicalize(path)) except SubversionException: + # svn.client.url_from_path() fails with local repositories pass if os.path.isdir(path): path = os.path.normpath(os.path.abspath(path)) @@ -62,8 +73,8 @@ # Module URL is later compared with the repository URL returned # by svn API, which is UTF-8. path = encoding.tolocal(path) - return 'file://%s' % urllib.quote(path) - return path + path = 'file://%s' % quote(path) + return svn.core.svn_path_canonicalize(path) def optrev(number): optrev = svn.core.svn_opt_revision_t() @@ -306,7 +317,7 @@ def exists(self, path, optrev): try: - svn.client.ls(self.url.rstrip('/') + '/' + urllib.quote(path), + svn.client.ls(self.url.rstrip('/') + '/' + quote(path), optrev, False, self.ctx) return True except SubversionException: @@ -358,7 +369,7 @@ # Check if branches bring a few more heads to the list if branches: rpath = self.url.strip('/') - branchnames = svn.client.ls(rpath + '/' + urllib.quote(branches), + branchnames = svn.client.ls(rpath + '/' + quote(branches), rev, False, self.ctx) for branch in branchnames.keys(): module = '%s/%s/%s' % (oldmodule, branches, branch) @@ -394,7 +405,7 @@ else: # Perform a full checkout on roots uuid, module, revnum = revsplit(rev) - entries = svn.client.ls(self.baseurl + urllib.quote(module), + entries = svn.client.ls(self.baseurl + quote(module), optrev(revnum), True, self.ctx) files = [n for n, e in entries.iteritems() if e.kind == svn.core.svn_node_file] @@ -595,7 +606,7 @@ """Reparent the svn transport and return the previous parent.""" if self.prevmodule == module: return module - svnurl = self.baseurl + urllib.quote(module) + svnurl = self.baseurl + quote(module) prevmodule = self.prevmodule if prevmodule is None: prevmodule = '' @@ -866,7 +877,7 @@ """Enumerate all files in path at revnum, recursively.""" path = path.strip('/') pool = Pool() - rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/') + rpath = '/'.join([self.baseurl, quote(path)]).strip('/') entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool) if path: path += '/'