dirstate: don't walk ignored directories
With a pattern like '^directory$' in .hgignore, a "hg status directory"
would still walk "directory" and all its subdirs.
This is the first half of a fix for
issue886.
--- a/mercurial/dirstate.py Fri Feb 08 18:07:55 2008 -0200
+++ b/mercurial/dirstate.py Fri Feb 08 18:07:55 2008 -0200
@@ -369,6 +369,14 @@
% (self.pathto(f), kind))
return False
+ def _dirignore(self, f):
+ if self._ignore(f):
+ return True
+ for c in strutil.findall(f, '/'):
+ if self._ignore(f[:c]):
+ return True
+ return False
+
def walk(self, files=None, match=util.always, badmatch=None):
# filter out the stat
for src, f, st in self.statwalk(files, match, badmatch=badmatch):
@@ -404,9 +412,11 @@
return match(file_)
ignore = self._ignore
+ dirignore = self._dirignore
if ignored:
imatch = match
ignore = util.never
+ dirignore = util.never
# self._root may end with a path separator when self._root == '/'
common_prefix_len = len(self._root)
@@ -492,8 +502,9 @@
yield 'b', ff, None
continue
if s_isdir(st.st_mode):
- for f, src, st in findfiles(f):
- yield src, f, st
+ if not dirignore(nf):
+ for f, src, st in findfiles(f):
+ yield src, f, st
else:
if nf in known:
continue
--- a/tests/test-walk Fri Feb 08 18:07:55 2008 -0200
+++ b/tests/test-walk Fri Feb 08 18:07:55 2008 -0200
@@ -92,6 +92,13 @@
debugwalk fenugreek
touch new
debugwalk new
+
+mkdir ignored
+touch ignored/file
+echo '^ignored$' > .hgignore
+debugwalk ignored
+debugwalk ignored/file
+
chdir ..
debugwalk -R t t/mammals/skunk
mkdir t2
--- a/tests/test-walk.out Fri Feb 08 18:07:55 2008 -0200
+++ b/tests/test-walk.out Fri Feb 08 18:07:55 2008 -0200
@@ -278,6 +278,11 @@
hg debugwalk new
f new new exact
+hg debugwalk ignored
+
+hg debugwalk ignored/file
+f ignored/file ignored/file exact
+
cd ..
hg debugwalk -R t t/mammals/skunk