cmdutil: reimplement finddate() without using walkchangerevs()
It's simpler and slightly faster maybe because a fewer Python ops would
run.
Unscientific benchmark:
$ python -m timeit \
-s 'from mercurial import hg, ui, cmdutil; repo = hg.repository(ui.ui())' \
'cmdutil.finddate(repo.ui, repo, "<2008-01-01")'
(orig) 10 loops, best of 3: 1.45 sec per loop
(new) 10 loops, best of 3: 1.25 sec per loop
Now "hg churn" and "hg grep" are the only users of walkchangerevs(), which
I want to refactor and fix bugs.
--- a/mercurial/cmdutil.py Sun Sep 13 18:14:51 2020 +0900
+++ b/mercurial/cmdutil.py Sun Sep 13 17:52:24 2020 +0900
@@ -2230,26 +2230,17 @@
def finddate(ui, repo, date):
"""Find the tipmost changeset that matches the given date spec"""
-
- df = dateutil.matchdate(date)
- m = scmutil.matchall(repo)
- results = {}
-
- def prep(ctx, fns):
- d = ctx.date()
- if df(d[0]):
- results[ctx.rev()] = d
-
- for ctx in walkchangerevs(repo, m, {b'rev': None}, prep):
- rev = ctx.rev()
- if rev in results:
- ui.status(
- _(b"found revision %d from %s\n")
- % (rev, dateutil.datestr(results[rev]))
- )
- return b'%d' % rev
-
- raise error.Abort(_(b"revision matching date not found"))
+ mrevs = repo.revs(b'date(%s)', date)
+ try:
+ rev = mrevs.max()
+ except ValueError:
+ raise error.Abort(_(b"revision matching date not found"))
+
+ ui.status(
+ _(b"found revision %d from %s\n")
+ % (rev, dateutil.datestr(repo[rev].date()))
+ )
+ return b'%d' % rev
def increasingwindows(windowsize=8, sizelimit=512):