[PATCH 2 of 2] revert: special case 'hg revert --all'
Durham Goode
durham at fb.com
Fri Sep 19 20:55:33 CDT 2014
On 9/19/14, 6:53 PM, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham at fb.com>
> # Date 1411177433 25200
> # Fri Sep 19 18:43:53 2014 -0700
> # Node ID 4ba21a38b9dc7d351e88cc575516443046f6d913
> # Parent b74b7d5f46d5d8ad13ca74e6b740970129090529
> revert: special case 'hg revert --all'
>
> On large repos, hg revert --all can take over 13 seconds. This is mainly due to
> it walking the tree three times: once to find the list of files in the
> dirstate, once to find the list of files in the target, and once to compute the
> status from the dirstate to the target.
>
> This optimizes the hg revert --all case to only require the final status. This
> speeds it up to 1.3 seconds or so (with hgwatchman enabled).
>
> Further optimizations could be done for the -r NODE and pattern cases, but they
> are significantly more complex.
>
This last patch looks big, but 'hg diff -w' shows you it's pretty tiny.
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2480,6 +2480,7 @@
# walk dirstate to fill `names`
m = scmutil.match(repo[None], pats, opts)
+ if not m.always() or node != parent:
m.bad = lambda x, y: False
for abs in repo.walk(m):
names[abs] = m.rel(abs), m.exact(abs)
@@ -2508,6 +2509,14 @@
changes = repo.status(node1=node, match=m,
unknown=True, ignored=True, clean=True)
+ else:
+ changes = repo.status(match=m)
+ for kind in changes:
+ for abs in kind:
+ names[abs] = m.rel(abs), m.exact(abs)
+
+ m = scmutil.matchfiles(repo, names)
+
modified = set(changes[0])
added = set(changes[1])
removed = set(changes[2])
More information about the Mercurial-devel
mailing list