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%).
--- 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))