dirstate: skip step 3 in walk if nothing new will match
authorSimon Heimberg <simohe@besonet.ch>
Thu, 14 May 2009 19:54:26 +0200
changeset 8589 3edf133dcb5a
parent 8588 2624f485b9bc
child 8590 59acb9c7d90f
dirstate: skip step 3 in walk if nothing new will match nothing will ever match on match.never nothing new will match on match.exact (all found in step 1) nothing new will match on match.match when there is no pattern and there is no direcory in pats
mercurial/dirstate.py
--- a/mercurial/dirstate.py	Thu May 14 10:50:45 2009 +0200
+++ b/mercurial/dirstate.py	Thu May 14 19:54:26 2009 +0200
@@ -461,6 +461,23 @@
         work = []
         wadd = work.append
 
+        if match.anypats():
+            #match.match with patterns
+            dostep3 = True
+            nomatches = False
+        elif not match.files():
+            #match.always or match.never
+            dostep3 = matchfn('')
+            nomatches = not dostep3
+        else:
+            #match.exact or match.match without pattern
+            dostep3 = False
+            nomatches = matchfn == match.exact
+
+        if nomatches:
+            #skip step 2
+            dirignore = util.always
+
         files = set(match.files())
         if not files or '.' in files:
             files = ['']
@@ -476,6 +493,7 @@
                 st = lstat(join(nf))
                 kind = getkind(st.st_mode)
                 if kind == dirkind:
+                    dostep3 = True
                     if nf in dmap:
                         #file deleted on disc but still in dirstate
                         results[nf] = None
@@ -497,6 +515,7 @@
                         keep = True
                         break
                     elif fn.startswith(prefix):
+                        dostep3 = True
                         keep = True
                         break
                 if not keep:
@@ -541,11 +560,12 @@
                         results[nf] = None
 
         # step 3: report unseen items in the dmap hash
-        visit = sorted([f for f in dmap if f not in results and matchfn(f)])
-        for nf, st in zip(visit, util.statfiles([join(i) for i in visit])):
-            if not st is None and not getkind(st.st_mode) in (regkind, lnkkind):
-                st = None
-            results[nf] = st
+        if dostep3 and not nomatches:
+            visit = sorted([f for f in dmap if f not in results and matchfn(f)])
+            for nf, st in zip(visit, util.statfiles([join(i) for i in visit])):
+                if not st is None and not getkind(st.st_mode) in (regkind, lnkkind):
+                    st = None
+                results[nf] = st
 
         del results['.hg']
         return results