issue 1286: dirstat regression on case folding systems
This patch fixes regression reported in 1286 that causes util.fspath
to be called for every file not in current manifest - including ignored files.
The regression is quite severe - the time for simple hg st goes from 5s to 1m38s
on one of my source trees - which basically renders mercurial useless.
--- a/mercurial/dirstate.py Wed Oct 08 16:22:10 2008 -0500
+++ b/mercurial/dirstate.py Tue Sep 30 17:23:08 2008 -0400
@@ -98,7 +98,7 @@
if self._checkcase:
self.normalize = self._normalize
else:
- self.normalize = lambda x: x
+ self.normalize = lambda x, y=False: x
return self.normalize
else:
raise AttributeError(name)
@@ -350,13 +350,16 @@
except KeyError:
self._ui.warn(_("not in dirstate: %s\n") % f)
- def _normalize(self, path):
+ def _normalize(self, path, knownpath=False):
norm_path = os.path.normcase(os.path.normpath(path))
- if norm_path not in self._foldmap:
- if not os.path.exists(os.path.join(self._root, path)):
- return path
- self._foldmap[norm_path] = util.fspath(path, self._root)
- return self._foldmap[norm_path]
+ fold_path = self._foldmap.get(norm_path, None)
+ if fold_path is None:
+ if knownpath or not os.path.exists(os.path.join(self._root, path)):
+ fold_path = path
+ else:
+ fold_path = self._foldmap.setdefault(norm_path,
+ util.fspath(path, self._root))
+ return fold_path
def clear(self):
self._map = {}
@@ -515,7 +518,7 @@
else:
entries = listdir(join(nd), stat=True, skip ='.hg')
for f, kind, st in entries:
- nf = normalize(nd and (nd + "/" + f) or f)
+ nf = normalize(nd and (nd + "/" + f) or f, True)
if nf not in results:
if kind == dirkind:
if not ignore(nf):