Mercurial > hg
comparison hgext/convert/subversion.py @ 7074:b1a4f67b98d0
convert: properly encode subversion URLs (issue 1224)
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Fri, 10 Oct 2008 11:36:02 +0200 |
parents | 1d38f3605b20 |
children | 6db6f6db026a 380fda3eed13 |
comparison
equal
deleted
inserted
replaced
7073:af1117f37fa7 | 7074:b1a4f67b98d0 |
---|---|
19 import os | 19 import os |
20 import re | 20 import re |
21 import sys | 21 import sys |
22 import cPickle as pickle | 22 import cPickle as pickle |
23 import tempfile | 23 import tempfile |
24 import urllib | |
24 | 25 |
25 from mercurial import strutil, util | 26 from mercurial import strutil, util |
26 from mercurial.i18n import _ | 27 from mercurial.i18n import _ |
27 | 28 |
28 # Subversion stuff. Works best with very recent Python SVN bindings | 29 # Subversion stuff. Works best with very recent Python SVN bindings |
52 pass | 53 pass |
53 if os.path.isdir(path): | 54 if os.path.isdir(path): |
54 path = os.path.normpath(os.path.abspath(path)) | 55 path = os.path.normpath(os.path.abspath(path)) |
55 if os.name == 'nt': | 56 if os.name == 'nt': |
56 path = '/' + util.normpath(path) | 57 path = '/' + util.normpath(path) |
57 return 'file://%s' % path | 58 return 'file://%s' % urllib.quote(path) |
58 return path | 59 return path |
59 | 60 |
60 def optrev(number): | 61 def optrev(number): |
61 optrev = svn.core.svn_opt_revision_t() | 62 optrev = svn.core.svn_opt_revision_t() |
62 optrev.kind = svn.core.svn_opt_revision_number | 63 optrev.kind = svn.core.svn_opt_revision_number |
170 self.encoding = 'UTF-8' # Subversion is always nominal UTF-8 | 171 self.encoding = 'UTF-8' # Subversion is always nominal UTF-8 |
171 try: | 172 try: |
172 self.transport = transport.SvnRaTransport(url=self.url) | 173 self.transport = transport.SvnRaTransport(url=self.url) |
173 self.ra = self.transport.ra | 174 self.ra = self.transport.ra |
174 self.ctx = self.transport.client | 175 self.ctx = self.transport.client |
175 self.base = svn.ra.get_repos_root(self.ra) | 176 self.baseurl = svn.ra.get_repos_root(self.ra) |
176 # Module is either empty or a repository path starting with | 177 # Module is either empty or a repository path starting with |
177 # a slash and not ending with a slash. | 178 # a slash and not ending with a slash. |
178 self.module = self.url[len(self.base):] | 179 self.module = urllib.unquote(self.url[len(self.baseurl):]) |
179 self.prevmodule = None | 180 self.prevmodule = None |
180 self.rootmodule = self.module | 181 self.rootmodule = self.module |
181 self.commits = {} | 182 self.commits = {} |
182 self.paths = {} | 183 self.paths = {} |
183 self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding) | 184 self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding) |
228 lastrevs[module] = revnum | 229 lastrevs[module] = revnum |
229 self.lastrevs = lastrevs | 230 self.lastrevs = lastrevs |
230 | 231 |
231 def exists(self, path, optrev): | 232 def exists(self, path, optrev): |
232 try: | 233 try: |
233 svn.client.ls(self.url.rstrip('/') + '/' + path, | 234 svn.client.ls(self.url.rstrip('/') + '/' + urllib.quote(path), |
234 optrev, False, self.ctx) | 235 optrev, False, self.ctx) |
235 return True | 236 return True |
236 except SubversionException, err: | 237 except SubversionException, err: |
237 return False | 238 return False |
238 | 239 |
277 self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags')) | 278 self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags')) |
278 | 279 |
279 # Check if branches bring a few more heads to the list | 280 # Check if branches bring a few more heads to the list |
280 if branches: | 281 if branches: |
281 rpath = self.url.strip('/') | 282 rpath = self.url.strip('/') |
282 branchnames = svn.client.ls(rpath + '/' + branches, rev, False, | 283 branchnames = svn.client.ls(rpath + '/' + urllib.quote(branches), |
283 self.ctx) | 284 rev, False, self.ctx) |
284 for branch in branchnames.keys(): | 285 for branch in branchnames.keys(): |
285 module = '%s/%s/%s' % (oldmodule, branches, branch) | 286 module = '%s/%s/%s' % (oldmodule, branches, branch) |
286 if not isdir(module, self.last_changed): | 287 if not isdir(module, self.last_changed): |
287 continue | 288 continue |
288 brevid = self.latest(module, self.last_changed) | 289 brevid = self.latest(module, self.last_changed) |
322 if parents: | 323 if parents: |
323 files, copies = self.expandpaths(rev, paths, parents) | 324 files, copies = self.expandpaths(rev, paths, parents) |
324 else: | 325 else: |
325 # Perform a full checkout on roots | 326 # Perform a full checkout on roots |
326 uuid, module, revnum = self.revsplit(rev) | 327 uuid, module, revnum = self.revsplit(rev) |
327 entries = svn.client.ls(self.base + module, optrev(revnum), | 328 entries = svn.client.ls(self.baseurl + urllib.quote(module), |
328 True, self.ctx) | 329 optrev(revnum), True, self.ctx) |
329 files = [n for n,e in entries.iteritems() | 330 files = [n for n,e in entries.iteritems() |
330 if e.kind == svn.core.svn_node_file] | 331 if e.kind == svn.core.svn_node_file] |
331 copies = {} | 332 copies = {} |
332 | 333 |
333 files.sort() | 334 files.sort() |
522 | 523 |
523 def reparent(self, module): | 524 def reparent(self, module): |
524 """Reparent the svn transport and return the previous parent.""" | 525 """Reparent the svn transport and return the previous parent.""" |
525 if self.prevmodule == module: | 526 if self.prevmodule == module: |
526 return module | 527 return module |
527 svn_url = (self.base + module).encode(self.encoding) | 528 svnurl = self.baseurl + urllib.quote(module) |
528 prevmodule = self.prevmodule | 529 prevmodule = self.prevmodule |
529 if prevmodule is None: | 530 if prevmodule is None: |
530 prevmodule = '' | 531 prevmodule = '' |
531 self.ui.debug("reparent to %s\n" % svn_url) | 532 self.ui.debug("reparent to %s\n" % svnurl) |
532 svn.ra.reparent(self.ra, svn_url) | 533 svn.ra.reparent(self.ra, svnurl) |
533 self.prevmodule = module | 534 self.prevmodule = module |
534 return prevmodule | 535 return prevmodule |
535 | 536 |
536 def expandpaths(self, rev, paths, parents): | 537 def expandpaths(self, rev, paths, parents): |
537 entries = [] | 538 entries = [] |
870 return data, mode | 871 return data, mode |
871 | 872 |
872 def _find_children(self, path, revnum): | 873 def _find_children(self, path, revnum): |
873 path = path.strip('/') | 874 path = path.strip('/') |
874 pool = Pool() | 875 pool = Pool() |
875 rpath = '/'.join([self.base, path]).strip('/') | 876 rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/') |
876 return ['%s/%s' % (path, x) for x in svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool).keys()] | 877 return ['%s/%s' % (path, x) for x in |
878 svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool).keys()] | |
877 | 879 |
878 def getrelpath(self, path, module=None): | 880 def getrelpath(self, path, module=None): |
879 if module is None: | 881 if module is None: |
880 module = self.module | 882 module = self.module |
881 # Given the repository url of this wc, say | 883 # Given the repository url of this wc, say |
907 relpaths = [] | 909 relpaths = [] |
908 for p in paths: | 910 for p in paths: |
909 if not p.startswith('/'): | 911 if not p.startswith('/'): |
910 p = self.module + '/' + p | 912 p = self.module + '/' + p |
911 relpaths.append(p.strip('/')) | 913 relpaths.append(p.strip('/')) |
912 args = [self.base, relpaths, start, end, limit, discover_changed_paths, | 914 args = [self.baseurl, relpaths, start, end, limit, discover_changed_paths, |
913 strict_node_history] | 915 strict_node_history] |
914 arg = encodeargs(args) | 916 arg = encodeargs(args) |
915 hgexe = util.hgexecutable() | 917 hgexe = util.hgexecutable() |
916 cmd = '%s debugsvnlog' % util.shellquote(hgexe) | 918 cmd = '%s debugsvnlog' % util.shellquote(hgexe) |
917 stdin, stdout = os.popen2(cmd, 'b') | 919 stdin, stdout = os.popen2(cmd, 'b') |