addremove: don't call lexists, isdir, and islink
authorDurham Goode <durham@fb.com>
Mon, 04 Feb 2013 14:06:20 -0800
changeset 18559 d1582dd6288e
parent 18558 eb95cf4e219d
child 18560 acf4a405e440
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%).
mercurial/scmutil.py
--- a/mercurial/scmutil.py	Mon Feb 04 14:01:40 2013 -0800
+++ b/mercurial/scmutil.py	Mon Feb 04 14:06:20 2013 -0800
@@ -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))