changeset 6820:639d9cb95509

dirstate.walk: fold findfiles into main walk loop
author Matt Mackall <mpm@selenic.com>
date Tue, 22 Jul 2008 13:03:10 -0500
parents 78624d74e194
children d8367107da05
files mercurial/dirstate.py
diffstat 1 files changed, 43 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/dirstate.py	Tue Jul 22 13:03:08 2008 -0500
+++ b/mercurial/dirstate.py	Tue Jul 22 13:03:10 2008 -0500
@@ -474,16 +474,50 @@
         s_isdir = stat.S_ISDIR
         supported = self._supported
         _join = self._join
+        work = []
+        wadd = work.append
+        found = []
+        add = found.append
+
         known = {'.hg': 1}
 
-        # recursion free walker, faster than os.walk.
-        def findfiles(s):
-            work = [s]
-            wadd = work.append
-            found = []
-            add = found.append
+        # step one, find all files that match our criteria
+        for ff in util.sort(files):
+            nf = normpath(ff)
+            nn = self.normalize(nf)
+            f = _join(ff)
+            if nn in known:
+                continue
+
+            try:
+                st = lstat(f)
+            except OSError, inst:
+                keep = False
+                for fn in dc:
+                    if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
+                        keep = True
+                        break
+                if not keep:
+                    if inst.errno != errno.ENOENT:
+                        fwarn(ff, inst.strerror)
+                    elif badfn(ff, inst.strerror) and imatch(nf):
+                        yield ff, None
+                continue
+
+            if not s_isdir(st.st_mode):
+                known[nn] = 1
+                if supported(ff, st.st_mode, verbose=True):
+                    yield self.normalize(nf), st
+                elif ff in dc:
+                    yield nf, None
+                continue
+
+            if dirignore(nf):
+                continue
+
             if hasattr(match, 'dir'):
-                match.dir(normpath(s[common_prefix_len:]))
+                match.dir(normpath(f[common_prefix_len:]))
+            wadd(f)
             while work:
                 top = work.pop()
                 entries = listdir(top, stat=True)
@@ -520,39 +554,8 @@
                             add((nn, st))
                         elif np in dc:
                             add((nn, None))
-            return util.sort(found)
-
-        # step one, find all files that match our criteria
-        for ff in util.sort(files):
-            nf = normpath(ff)
-            nn = self.normalize(nf)
-            f = _join(ff)
-            try:
-                st = lstat(f)
-            except OSError, inst:
-                found = False
-                for fn in dc:
-                    if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
-                        found = True
-                        break
-                if not found:
-                    if inst.errno != errno.ENOENT:
-                        fwarn(ff, inst.strerror)
-                    elif badfn(ff, inst.strerror) and imatch(nf):
-                        yield ff, None
-                continue
-            if s_isdir(st.st_mode):
-                if not dirignore(nf):
-                    for e in findfiles(f):
-                        yield e
-            else:
-                if nn in known:
-                    continue
-                known[nn] = 1
-                if supported(ff, st.st_mode, verbose=True):
-                    yield self.normalize(nf), st
-                elif ff in dc:
-                    yield nf, None
+            for e in util.sort(found):
+                yield e
 
         # step two run through anything left in the dc hash and yield
         # if we haven't already seen it