Patchwork [3,of,3] addremove: don't audit the path for paths already in the dirstate

login
register
mail settings
Submitter Durham Goode
Date Feb. 10, 2013, 2:29 p.m.
Message ID <9e92bbb4ec6be418981d.1360506578@dev350.prn1.facebook.com>
Download mbox | patch
Permalink /patch/932/
State Superseded
Commit b114e41c4df3b0c57b4bedcccaa2af1a908b853b
Headers show

Comments

Durham Goode - Feb. 10, 2013, 2:29 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1360103779 28800
# Node ID 9e92bbb4ec6be418981d7854ab75e42789cd29c4
# Parent  574375cb530f2ec3c9abfec42327460fac4eacf2
addremove: don't audit the path for paths already in the dirstate

Now that dirstate.walk returns None for paths under symlink directories,
addremove doesn't need to validate each path it sees to look for files
under symlinks.

On a large repository this brings addremove from 6.3 seconds down to 3.65 (42%)
since addremove no longer has to stat every directory of every file to determine
if the file is inside a symlink directory. I put it through our benchmark and
see no perf hit to any other commands.

Patch

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -686,7 +686,7 @@ 
                 for nf in iter(visit):
                     # Report ignored items in the dmap as long as they are not
                     # under a symlink directory.
-                    if ignore(nf) and audit_path.isvalidpath(nf):
+                    if ignore(nf) and audit_path.check(nf):
                         results[nf] = util.statfiles([join(nf)])[0]
                     else:
                         # It's either missing or under a symlink directory
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -752,17 +752,14 @@ 
     ctx = repo[None]
     walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
     for abs in sorted(walkresults):
-        good = audit_path.check(abs)
-
         st = walkresults[abs]
         dstate = repo.dirstate[abs]
-        if good and dstate == '?':
+        if dstate == '?' and audit_path.check(abs):
             unknown.append(abs)
             if repo.ui.verbose or not m.exact(abs):
                 rel = m.rel(abs)
                 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
-        elif (dstate != 'r' and
-              (not good or not st or
+        elif (dstate != 'r' and (not st or
                (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))):
             deleted.append(abs)
             if repo.ui.verbose or not m.exact(abs):