# HG changeset patch # User Yuya Nishihara # Date 2020-09-13 08:52:24 # Node ID d2b5a7659fff465286c7a1a451f0ebfe7118f251 # Parent 65960fe9a769cda02e37cc36f953f9e2e624d234 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. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2230,26 +2230,17 @@ def showmarker(fm, marker, index=None): 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):