Patchwork [4,of,6] dirstate.walk: refactor explicit walk into separate function

login
register
mail settings
Submitter Siddharth Agarwal
Date May 7, 2013, 9:32 p.m.
Message ID <935ab007bcdcf391c9bb.1367962331@dev1091.prn1.facebook.com>
Download mbox | patch
Permalink /patch/1586/
State Accepted
Commit ec70a78a70e03039ec7b01f38b75fa8c1ee1013d
Headers show

Comments

Siddharth Agarwal - May 7, 2013, 9:32 p.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1367946175 25200
#      Tue May 07 10:02:55 2013 -0700
# Node ID 935ab007bcdcf391c9bb4c9e5dfff2a0f5c803ac
# Parent  99df5ff49e9082a86d20e8258a7cb69a304b1ec1
dirstate.walk: refactor explicit walk into separate function

This enables this code to be reused by extensions that implement the other,
more time-consuming bits of walk in different ways.

Patch

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -522,18 +522,15 @@ 
                 return True
         return False
 
-    def walk(self, match, subrepos, unknown, ignored):
-        '''
-        Walk recursively through the directory tree, finding all files
-        matched by match.
+    def _walkexplicit(self, match, subrepos):
+        '''Get stat data about the files explicitly specified by match.
 
-        Return a dict mapping filename to stat-like object (either
-        mercurial.osutil.stat instance or return value of os.stat()).
-        '''
-
-        def fwarn(f, msg):
-            self._ui.warn('%s: %s\n' % (self.pathto(f), msg))
-            return False
+        Return a triple (results, work, dirsnotfound).
+        - results is a mapping from filename to stat result. It also contains
+          listings mapping subrepos and .hg to None.
+        - work is a list of files found to be directories.
+        - dirsnotfound is a list of files that the dirstate thinks are
+          directories and that were not found.'''
 
         def badtype(mode):
             kind = _('unknown')
@@ -549,24 +546,10 @@ 
                 kind = _('directory')
             return _('unsupported file type (type is %s)') % kind
 
-        ignore = self._ignore
-        dirignore = self._dirignore
-        if ignored:
-            ignore = util.never
-            dirignore = util.never
-        elif not unknown:
-            # if unknown and ignored are False, skip step 2
-            ignore = util.always
-            dirignore = util.always
-
-        matchfn = match.matchfn
-        matchalways = match.always()
         matchedir = match.explicitdir
-        matchtdir = match.traversedir
         badfn = match.bad
         dmap = self._map
         normpath = util.normpath
-        listdir = osutil.listdir
         lstat = os.lstat
         getkind = stat.S_IFMT
         dirkind = stat.S_IFDIR
@@ -575,17 +558,10 @@ 
         join = self._join
         work = []
         wadd = work.append
+        dirsnotfound = []
 
-        exact = skipstep3 = False
-        if matchfn == match.exact: # match.exact
-            exact = True
-            dirignore = util.always # skip step 2
-        elif match.files() and not match.anypats(): # match.match, no patterns
-            skipstep3 = True
-
-        if not exact and self._checkcase:
+        if match.matchfn != match.exact and self._checkcase:
             normalize = self._normalize
-            skipstep3 = False
         else:
             normalize = None
 
@@ -606,8 +582,6 @@ 
         results = dict.fromkeys(subrepos)
         results['.hg'] = None
 
-        # step 1: find all explicit files
-        dirsnotfound = []
         for ff in files:
             if normalize:
                 nf = normalize(normpath(ff), False, True)
@@ -646,6 +620,58 @@ 
                     else:
                         badfn(ff, inst.strerror)
 
+        return results, work, dirsnotfound
+
+    def walk(self, match, subrepos, unknown, ignored):
+        '''
+        Walk recursively through the directory tree, finding all files
+        matched by match.
+
+        Return a dict mapping filename to stat-like object (either
+        mercurial.osutil.stat instance or return value of os.stat()).
+        '''
+
+        def fwarn(f, msg):
+            self._ui.warn('%s: %s\n' % (self.pathto(f), msg))
+            return False
+
+        ignore = self._ignore
+        dirignore = self._dirignore
+        if ignored:
+            ignore = util.never
+            dirignore = util.never
+        elif not unknown:
+            # if unknown and ignored are False, skip step 2
+            ignore = util.always
+            dirignore = util.always
+
+        matchfn = match.matchfn
+        matchalways = match.always()
+        matchtdir = match.traversedir
+        dmap = self._map
+        listdir = osutil.listdir
+        lstat = os.lstat
+        dirkind = stat.S_IFDIR
+        regkind = stat.S_IFREG
+        lnkkind = stat.S_IFLNK
+        join = self._join
+
+        exact = skipstep3 = False
+        if matchfn == match.exact: # match.exact
+            exact = True
+            dirignore = util.always # skip step 2
+        elif match.files() and not match.anypats(): # match.match, no patterns
+            skipstep3 = True
+
+        if not exact and self._checkcase:
+            normalize = self._normalize
+            skipstep3 = False
+        else:
+            normalize = None
+
+        # step 1: find all explicit files
+        results, work, dirsnotfound = self._walkexplicit(match, subrepos)
+
         skipstep3 = skipstep3 and not (work or dirsnotfound)
         work = [d for d in work if not dirignore(d)]
         wadd = work.append