Patchwork [1,of,2] repair: speed up stripping of many roots

login
register
mail settings
Submitter via Mercurial-devel
Date Jan. 4, 2017, 6:52 p.m.
Message ID <acf0037a9a5bb14603bb.1483555977@martinvonz.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/18094/
State Accepted
Headers show

Comments

via Mercurial-devel - Jan. 4, 2017, 6:52 p.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1483553232 28800
#      Wed Jan 04 10:07:12 2017 -0800
# Node ID acf0037a9a5bb14603bb50c57822d4ab5896e5b5
# Parent  0064a1eb28e246ded9b726c696d048143d1b23f1
repair: speed up stripping of many roots

repair.strip() expects a set of root revisions to strip. It then
builds the full set of descedants by walking the descandants of
each. It is rare that more than a few roots get passed in, but if that
happens, it will wastefully walk the changelog for each root. So let's
just walk it once.

I noticed this because the narrowhg extension was passing not only
roots, but all the commits to strip. When there were tens of thousands
of commits to strip, this resulted in quadratic behavior with that
extension.

Patch

diff -r 0064a1eb28e2 -r acf0037a9a5b mercurial/repair.py
--- a/mercurial/repair.py	Mon Dec 26 00:02:42 2016 +0000
+++ b/mercurial/repair.py	Wed Jan 04 10:07:12 2017 -0800
@@ -99,9 +99,9 @@ 
     # (head = revision in the set that has no descendant in the set;
     #  base = revision in the set that has no ancestor in the set)
     tostrip = set(striplist)
-    for rev in striplist:
-        for desc in cl.descendants([rev]):
-            tostrip.add(desc)
+    for r in cl.revs(start=striprev + 1):
+        if any(p in tostrip for p in cl.parentrevs(r)):
+            tostrip.add(r)
 
     files = _collectfiles(repo, striprev)
     saverevs = _collectbrokencsets(repo, files, striprev)