Patchwork [2,of,7] scmutil: move walkchangerevs() from cmdutil

login
register
mail settings
Submitter Yuya Nishihara
Date Oct. 14, 2020, 2:13 p.m.
Message ID <09a598f9d9790918f47f.1602684812@mimosa>
Download mbox | patch
Permalink /patch/47457/
State Accepted
Headers show

Comments

Yuya Nishihara - Oct. 14, 2020, 2:13 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1601785077 -32400
#      Sun Oct 04 13:17:57 2020 +0900
# Node ID 09a598f9d9790918f47f66b6ce5e51f198510289
# Parent  d36d703c291e45670245384440993ff70ad17da4
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.

Patch

diff --git a/hgext/churn.py b/hgext/churn.py
--- a/hgext/churn.py
+++ b/hgext/churn.py
@@ -23,6 +23,7 @@  from mercurial import (
     patch,
     pycompat,
     registrar,
+    scmutil,
 )
 
 cmdtable = {}
@@ -98,7 +99,7 @@  def countrate(ui, repo, amap, *pats, **o
         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()
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2240,55 +2240,6 @@  def finddate(ui, repo, date):
     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 = []
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3532,7 +3532,7 @@  def grep(ui, repo, pattern, *pats, **opt
 
     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()
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -760,6 +760,55 @@  def revrange(repo, specs, localalias=Non
     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.