--- a/mercurial/util.py Tue Jan 17 11:29:32 2012 +0100
+++ b/mercurial/util.py Thu Jan 19 14:34:32 2012 -0600
@@ -77,6 +77,11 @@
# Python compatibility
+_notset = object()
+
+def safehasattr(thing, attr):
+ return getattr(thing, attr, _notset) is not _notset
+
def sha1(s=''):
'''
Low-overhead wrapper around Python's SHA support
@@ -90,10 +95,6 @@
return _fastsha1(s)
-_notset = object()
-def safehasattr(thing, attr):
- return getattr(thing, attr, _notset) is not _notset
-
def _fastsha1(s=''):
# This function will import sha1 from hashlib or sha (whichever is
# available) and overwrite itself with it on the first call.
@@ -106,18 +107,15 @@
_fastsha1 = sha1 = _sha1
return _sha1(s)
-import __builtin__
-
-if sys.version_info[0] < 3:
- def fakebuffer(sliceable, offset=0):
- return sliceable[offset:]
-else:
- def fakebuffer(sliceable, offset=0):
- return memoryview(sliceable)[offset:]
try:
- buffer
+ buffer = buffer
except NameError:
- __builtin__.buffer = fakebuffer
+ if sys.version_info[0] < 3:
+ def buffer(sliceable, offset=0):
+ return sliceable[offset:]
+ else:
+ def buffer(sliceable, offset=0):
+ return memoryview(sliceable)[offset:]
import subprocess
closefds = os.name == 'posix'
@@ -616,20 +614,17 @@
def fspath(name, root):
'''Get name in the case stored in the filesystem
- The name is either relative to root, or it is an absolute path starting
- with root. Note that this function is unnecessary, and should not be
+ The name should be relative to root, and be normcase-ed for efficiency.
+
+ Note that this function is unnecessary, and should not be
called, for case-sensitive filesystems (simply because it's expensive).
- Both name and root should be normcase-ed.
+ The root should be normcase-ed, too.
'''
- # If name is absolute, make it relative
- if name.startswith(root):
- l = len(root)
- if name[l] == os.sep or name[l] == os.altsep:
- l = l + 1
- name = name[l:]
-
- if not os.path.lexists(os.path.join(root, name)):
+ def find(p, contents):
+ for n in contents:
+ if normcase(n) == p:
+ return n
return None
seps = os.sep
@@ -649,14 +644,15 @@
_fspathcache[dir] = os.listdir(dir)
contents = _fspathcache[dir]
- lenp = len(part)
- for n in contents:
- if lenp == len(n) and normcase(n) == part:
- result.append(n)
- break
- else:
- # Cannot happen, as the file exists!
- result.append(part)
+ found = find(part, contents)
+ if not found:
+ # retry "once per directory" per "dirstate.walk" which
+ # may take place for each patches of "hg qpush", for example
+ contents = os.listdir(dir)
+ _fspathcache[dir] = contents
+ found = find(part, contents)
+
+ result.append(found or part)
dir = os.path.join(dir, part)
return ''.join(result)
@@ -1502,7 +1498,7 @@
"""
_safechars = "!~*'()+"
- _safepchars = "/!~*'()+"
+ _safepchars = "/!~*'()+:"
_matchscheme = re.compile(r'^[a-zA-Z0-9+.\-]+:').match
def __init__(self, path, parsequery=True, parsefragment=True):
@@ -1614,8 +1610,8 @@
Examples:
- >>> str(url('http://user:pw@host:80/?foo#bar'))
- 'http://user:pw@host:80/?foo#bar'
+ >>> str(url('http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
+ 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
>>> str(url('http://user:pw@host:80/?foo=bar&baz=42'))
'http://user:pw@host:80/?foo=bar&baz=42'
>>> str(url('http://user:pw@host:80/?foo=bar%3dbaz'))
@@ -1637,7 +1633,7 @@
>>> str(url('file:///tmp/foo/bar'))
'file:///tmp/foo/bar'
>>> str(url('file:///c:/tmp/foo/bar'))
- 'file:///c%3A/tmp/foo/bar'
+ 'file:///c:/tmp/foo/bar'
>>> print url(r'bundle:foo\bar')
bundle:foo\bar
"""