Patchwork add: pass full=False to dirstate walk

login
register
mail settings
Submitter Durham Goode
Date Sept. 9, 2015, 4:15 p.m.
Message ID <8cb6ff7fe29e8ebbe37d.1441815322@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/10442/
State Accepted
Headers show

Comments

Durham Goode - Sept. 9, 2015, 4:15 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1441814847 25200
#      Wed Sep 09 09:07:27 2015 -0700
# Node ID 8cb6ff7fe29e8ebbe37d01f8a6cf26aad253d2f1
# Parent  a8eeffb15ed4bf1e55bc3b36baa64c8f2b5d0739
add: pass full=False to dirstate walk

Previously cmdutil.add would call wctx.walk(), which under the hood calls
dirstate.walk with full=True. This means it returns all of the clean files
(which we don't need when computing the add set), as well as the unclean files.
This results in 1) a lot more work being done and 2) this code path
circumventing the hgwatchman extension, resulting in worse performance in
hgwatchman environments ('hg add .' went from 9s to 1.8s).
Matt Mackall - Sept. 9, 2015, 7:55 p.m.
On Wed, 2015-09-09 at 09:15 -0700, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1441814847 25200
> #      Wed Sep 09 09:07:27 2015 -0700
> # Node ID 8cb6ff7fe29e8ebbe37d01f8a6cf26aad253d2f1
> # Parent  a8eeffb15ed4bf1e55bc3b36baa64c8f2b5d0739
> add: pass full=False to dirstate walk

Queued for default, thanks.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2208,7 +2208,12 @@  def add(ui, repo, match, prefix, explici
     if abort or warn:
         cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
 
-    for f in wctx.walk(matchmod.badmatch(match, badfn)):
+    badmatch = matchmod.badmatch(match, badfn)
+    dirstate = repo.dirstate
+    # We don't want to just call wctx.walk here, since it would return a lot of
+    # clean files, which we aren't interested in and takes time.
+    for f in sorted(dirstate.walk(badmatch, sorted(wctx.substate),
+                                  True, False, full=False)):
         exact = match.exact(f)
         if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
             if cca: