diff -r bb3334806ace -r e596a631210e mercurial/dirstate.py --- a/mercurial/dirstate.py Sat Apr 28 02:00:04 2012 +0200 +++ b/mercurial/dirstate.py Sat Apr 28 20:29:21 2012 +0200 @@ -408,32 +408,48 @@ self._droppath(f) del self._map[f] - def _normalize(self, path, isknown): + def _normalize(self, path, isknown, ignoremissing=False, exists=None): normed = util.normcase(path) folded = self._foldmap.get(normed, None) if folded is None: - if isknown or not os.path.lexists(os.path.join(self._root, path)): + if isknown: folded = path else: - # recursively normalize leading directory components - # against dirstate - if '/' in normed: - d, f = normed.rsplit('/', 1) - d = self._normalize(d, isknown) - r = self._root + "/" + d - folded = d + "/" + util.fspath(f, r) + if exists is None: + exists = os.path.lexists(os.path.join(self._root, path)) + if not exists: + # Maybe a path component exists + if not ignoremissing and '/' in path: + d, f = path.rsplit('/', 1) + d = self._normalize(d, isknown, ignoremissing, None) + folded = d + "/" + f + else: + # No path components, preserve original case + folded = path else: - folded = util.fspath(normed, self._root) - self._foldmap[normed] = folded + # recursively normalize leading directory components + # against dirstate + if '/' in normed: + d, f = normed.rsplit('/', 1) + d = self._normalize(d, isknown, ignoremissing, True) + r = self._root + "/" + d + folded = d + "/" + util.fspath(f, r) + else: + folded = util.fspath(normed, self._root) + self._foldmap[normed] = folded return folded - def normalize(self, path, isknown=False): + def normalize(self, path, isknown=False, ignoremissing=False): ''' normalize the case of a pathname when on a casefolding filesystem isknown specifies whether the filename came from walking the - disk, to avoid extra filesystem access + disk, to avoid extra filesystem access. + + If ignoremissing is True, missing path are returned + unchanged. Otherwise, we try harder to normalize possibly + existing path components. The normalized case is determined based on the following precedence: @@ -443,7 +459,7 @@ ''' if self._checkcase: - return self._normalize(path, isknown) + return self._normalize(path, isknown, ignoremissing) return path def clear(self): @@ -575,7 +591,7 @@ normalize = self._normalize skipstep3 = False else: - normalize = lambda x, y: x + normalize = lambda x, y, z: x files = sorted(match.files()) subrepos.sort() @@ -596,7 +612,7 @@ # step 1: find all explicit files for ff in files: - nf = normalize(normpath(ff), False) + nf = normalize(normpath(ff), False, True) if nf in results: continue @@ -646,7 +662,7 @@ continue raise for f, kind, st in entries: - nf = normalize(nd and (nd + "/" + f) or f, True) + nf = normalize(nd and (nd + "/" + f) or f, True, True) if nf not in results: if kind == dirkind: if not ignore(nf):