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

Durham Goode durham at fb.com
Tue Feb 5 17:38:40 CST 2013

# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1360103779 28800
# Node ID e46991c51de8f024a7167648ccfea31dc2469a07
# Parent  edbb3ea6c81389151eca1f352cbd7265cc47fd42
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.

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -743,17 +743,14 @@
     ctx = repo[None]
     walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
     for abs in sorted(walkresults):
-        good = audit_path.isvalidpath(abs)
         st = walkresults[abs]
         dstate = repo.dirstate[abs]
-        if good and dstate == '?':
+        if dstate == '?' and audit_path.isvalidpath(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)))):
             if repo.ui.verbose or not m.exact(abs):

More information about the Mercurial-devel mailing list