comparison mercurial/cmdutil.py @ 45468:d2b5a7659fff

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.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 13 Sep 2020 17:52:24 +0900
parents 6ba7190ff863
children 3dc848d5ec77
comparison
equal deleted inserted replaced
45467:65960fe9a769 45468:d2b5a7659fff
2228 fm.plain(b'\n') 2228 fm.plain(b'\n')
2229 2229
2230 2230
2231 def finddate(ui, repo, date): 2231 def finddate(ui, repo, date):
2232 """Find the tipmost changeset that matches the given date spec""" 2232 """Find the tipmost changeset that matches the given date spec"""
2233 2233 mrevs = repo.revs(b'date(%s)', date)
2234 df = dateutil.matchdate(date) 2234 try:
2235 m = scmutil.matchall(repo) 2235 rev = mrevs.max()
2236 results = {} 2236 except ValueError:
2237 2237 raise error.Abort(_(b"revision matching date not found"))
2238 def prep(ctx, fns): 2238
2239 d = ctx.date() 2239 ui.status(
2240 if df(d[0]): 2240 _(b"found revision %d from %s\n")
2241 results[ctx.rev()] = d 2241 % (rev, dateutil.datestr(repo[rev].date()))
2242 2242 )
2243 for ctx in walkchangerevs(repo, m, {b'rev': None}, prep): 2243 return b'%d' % rev
2244 rev = ctx.rev()
2245 if rev in results:
2246 ui.status(
2247 _(b"found revision %d from %s\n")
2248 % (rev, dateutil.datestr(results[rev]))
2249 )
2250 return b'%d' % rev
2251
2252 raise error.Abort(_(b"revision matching date not found"))
2253 2244
2254 2245
2255 def increasingwindows(windowsize=8, sizelimit=512): 2246 def increasingwindows(windowsize=8, sizelimit=512):
2256 while True: 2247 while True:
2257 yield windowsize 2248 yield windowsize