[PATCH 2 of 4] addremove: don't call lexists, isdir, and islink

Durham Goode durham at fb.com
Mon Feb 4 21:20:47 CST 2013


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1360015580 28800
# Node ID f8d0ae2b9805840a73f4c3e44d64043cf47691de
# Parent  3457575aad13d6e7b8ccb9a45f9e49cf1f2b27fe
addremove: don't call lexists, isdir, and islink

The dirstate walk results contain the stat information for each path, so we
don't need to query it again.  On a large repo this makes addremove go from
8.35 seconds to 7.1 (15%).

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -733,8 +733,9 @@
     rejected = []
     m.bad = lambda x, y: rejected.append(x)
 
-    for abs in repo.walk(m):
-        target = repo.wjoin(abs)
+    ctx = repo[None]
+    walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
+    for abs in sorted(walkresults):
         good = True
         try:
             audit_path(abs)
@@ -743,14 +744,15 @@
         rel = m.rel(abs)
         exact = m.exact(abs)
 
+        st = walkresults[abs]
         dstate = repo.dirstate[abs]
         if good and dstate == '?':
             unknown.append(abs)
             if repo.ui.verbose or not exact:
                 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
         elif (dstate != 'r' and
-              (not good or not os.path.lexists(target) or
-               (os.path.isdir(target) and not os.path.islink(target)))):
+              (not good or 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 exact:
                 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))


More information about the Mercurial-devel mailing list