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')