changeset 45720:508dfd1c18df

scmutil: move walkchangerevs() from cmdutil It's no longer a command-level function, but a pure helper to walk revisions in a windowed way. This change will help eliminate reverse dependency of revset.py -> grep.py -> cmdutil.py in future patches.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 04 Oct 2020 13:17:57 +0900
parents c10c87c8fe79
children f9d3ff23bfc0
files hgext/churn.py mercurial/cmdutil.py mercurial/commands.py mercurial/scmutil.py
diffstat 4 files changed, 52 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/churn.py	Wed Sep 09 17:04:44 2020 +0900
+++ b/hgext/churn.py	Sun Oct 04 13:17:57 2020 +0900
@@ -23,6 +23,7 @@
     patch,
     pycompat,
     registrar,
+    scmutil,
 )
 
 cmdtable = {}
@@ -98,7 +99,7 @@
         exclude_pats=opts[b'exclude'],
     )
     revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
-    for ctx in cmdutil.walkchangerevs(repo, revs, makefilematcher, prep):
+    for ctx in scmutil.walkchangerevs(repo, revs, makefilematcher, prep):
         continue
 
     progress.complete()
--- a/mercurial/cmdutil.py	Wed Sep 09 17:04:44 2020 +0900
+++ b/mercurial/cmdutil.py	Sun Oct 04 13:17:57 2020 +0900
@@ -2240,55 +2240,6 @@
     return b'%d' % rev
 
 
-def increasingwindows(windowsize=8, sizelimit=512):
-    while True:
-        yield windowsize
-        if windowsize < sizelimit:
-            windowsize *= 2
-
-
-def walkchangerevs(repo, revs, makefilematcher, prepare):
-    '''Iterate over files and the revs in a "windowed" way.
-
-    Callers most commonly need to iterate backwards over the history
-    in which they are interested. Doing so has awful (quadratic-looking)
-    performance, so we use iterators in a "windowed" way.
-
-    We walk a window of revisions in the desired order.  Within the
-    window, we first walk forwards to gather data, then in the desired
-    order (usually backwards) to display it.
-
-    This function returns an iterator yielding contexts. Before
-    yielding each context, the iterator will first call the prepare
-    function on each context in the window in forward order.'''
-
-    if not revs:
-        return []
-    change = repo.__getitem__
-
-    def iterate():
-        it = iter(revs)
-        stopiteration = False
-        for windowsize in increasingwindows():
-            nrevs = []
-            for i in pycompat.xrange(windowsize):
-                rev = next(it, None)
-                if rev is None:
-                    stopiteration = True
-                    break
-                nrevs.append(rev)
-            for rev in sorted(nrevs):
-                ctx = change(rev)
-                prepare(ctx, makefilematcher(ctx))
-            for rev in nrevs:
-                yield change(rev)
-
-            if stopiteration:
-                break
-
-    return iterate()
-
-
 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts):
     bad = []
 
--- a/mercurial/commands.py	Wed Sep 09 17:04:44 2020 +0900
+++ b/mercurial/commands.py	Sun Oct 04 13:17:57 2020 +0900
@@ -3532,7 +3532,7 @@
 
     ui.pager(b'grep')
     fm = ui.formatter(b'grep', opts)
-    for ctx in cmdutil.walkchangerevs(
+    for ctx in scmutil.walkchangerevs(
         repo, revs, makefilematcher, searcher._prep
     ):
         rev = ctx.rev()
--- a/mercurial/scmutil.py	Wed Sep 09 17:04:44 2020 +0900
+++ b/mercurial/scmutil.py	Sun Oct 04 13:17:57 2020 +0900
@@ -760,6 +760,55 @@
     return repo.anyrevs(allspecs, user=True, localalias=localalias)
 
 
+def increasingwindows(windowsize=8, sizelimit=512):
+    while True:
+        yield windowsize
+        if windowsize < sizelimit:
+            windowsize *= 2
+
+
+def walkchangerevs(repo, revs, makefilematcher, prepare):
+    '''Iterate over files and the revs in a "windowed" way.
+
+    Callers most commonly need to iterate backwards over the history
+    in which they are interested. Doing so has awful (quadratic-looking)
+    performance, so we use iterators in a "windowed" way.
+
+    We walk a window of revisions in the desired order.  Within the
+    window, we first walk forwards to gather data, then in the desired
+    order (usually backwards) to display it.
+
+    This function returns an iterator yielding contexts. Before
+    yielding each context, the iterator will first call the prepare
+    function on each context in the window in forward order.'''
+
+    if not revs:
+        return []
+    change = repo.__getitem__
+
+    def iterate():
+        it = iter(revs)
+        stopiteration = False
+        for windowsize in increasingwindows():
+            nrevs = []
+            for i in pycompat.xrange(windowsize):
+                rev = next(it, None)
+                if rev is None:
+                    stopiteration = True
+                    break
+                nrevs.append(rev)
+            for rev in sorted(nrevs):
+                ctx = change(rev)
+                prepare(ctx, makefilematcher(ctx))
+            for rev in nrevs:
+                yield change(rev)
+
+            if stopiteration:
+                break
+
+    return iterate()
+
+
 def meaningfulparents(repo, ctx):
     """Return list of meaningful (or all if debug) parentrevs for rev.