util: fix url.__str__() for windows file URLs
Before:
>>> str(url('file:///c:/tmp/foo/bar'))
'file:c%3C/tmp/foo/bar'
After:
>>> str(url('file:///c:/tmp/foo/bar'))
'file:///c%3C/tmp/foo/bar'
The previous behaviour had no effect on mercurial itself (clone command for
instance) because we fortunately called .localpath() on the parsed URL.
hgsubversion was not so lucky and cloning a local subversion repository on
Windows no longer worked on the default branch (it works on stable because
de7e2fba4326 defeats the hasdriveletter() test in url class).
I do not know if the %3C is correct or not but svn accepts file:// URLs
containing it. Mads fixed it in
de7e2fba4326, so we can always backport should
the need arise.
--- a/hgext/schemes.py Fri Dec 02 21:38:57 2011 -0200
+++ b/hgext/schemes.py Sun Dec 04 18:22:25 2011 +0100
@@ -72,9 +72,10 @@
return hg._peerlookup(url).instance(ui, url, create)
def hasdriveletter(orig, path):
- for scheme in schemes:
- if path.startswith(scheme + ':'):
- return False
+ if path:
+ for scheme in schemes:
+ if path.startswith(scheme + ':'):
+ return False
return orig(path)
schemes = {
--- a/mercurial/util.py Fri Dec 02 21:38:57 2011 -0200
+++ b/mercurial/util.py Sun Dec 04 18:22:25 2011 +0100
@@ -1629,6 +1629,8 @@
'path'
>>> str(url('file:///tmp/foo/bar'))
'file:///tmp/foo/bar'
+ >>> str(url('file:///c:/tmp/foo/bar'))
+ 'file:///c%3A/tmp/foo/bar'
>>> print url(r'bundle:foo\bar')
bundle:foo\bar
"""
@@ -1643,8 +1645,11 @@
s = self.scheme + ':'
if self.user or self.passwd or self.host:
s += '//'
- elif self.scheme and (not self.path or self.path.startswith('/')):
+ elif self.scheme and (not self.path or self.path.startswith('/')
+ or hasdriveletter(self.path)):
s += '//'
+ if hasdriveletter(self.path):
+ s += '/'
if self.user:
s += urllib.quote(self.user, safe=self._safechars)
if self.passwd:
@@ -1716,7 +1721,7 @@
return bool(url(path).scheme)
def hasdriveletter(path):
- return path[1:2] == ':' and path[0:1].isalpha()
+ return path and path[1:2] == ':' and path[0:1].isalpha()
def urllocalpath(path):
return url(path, parsequery=False, parsefragment=False).localpath()
--- a/tests/test-url.py Fri Dec 02 21:38:57 2011 -0200
+++ b/tests/test-url.py Sun Dec 04 18:22:25 2011 +0100
@@ -219,7 +219,7 @@
>>> u
<url scheme: 'file', path: 'f:oo/bar/baz'>
>>> str(u)
- 'file:f%3Aoo/bar/baz'
+ 'file:///f%3Aoo/bar/baz'
>>> u.localpath()
'f:oo/bar/baz'