comparison mercurial/cmdutil.py @ 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 9628d3cd9d13
children 96fcc37a9c80
comparison
equal deleted inserted replaced
45719:c10c87c8fe79 45720:508dfd1c18df
2238 % (rev, dateutil.datestr(repo[rev].date())) 2238 % (rev, dateutil.datestr(repo[rev].date()))
2239 ) 2239 )
2240 return b'%d' % rev 2240 return b'%d' % rev
2241 2241
2242 2242
2243 def increasingwindows(windowsize=8, sizelimit=512):
2244 while True:
2245 yield windowsize
2246 if windowsize < sizelimit:
2247 windowsize *= 2
2248
2249
2250 def walkchangerevs(repo, revs, makefilematcher, prepare):
2251 '''Iterate over files and the revs in a "windowed" way.
2252
2253 Callers most commonly need to iterate backwards over the history
2254 in which they are interested. Doing so has awful (quadratic-looking)
2255 performance, so we use iterators in a "windowed" way.
2256
2257 We walk a window of revisions in the desired order. Within the
2258 window, we first walk forwards to gather data, then in the desired
2259 order (usually backwards) to display it.
2260
2261 This function returns an iterator yielding contexts. Before
2262 yielding each context, the iterator will first call the prepare
2263 function on each context in the window in forward order.'''
2264
2265 if not revs:
2266 return []
2267 change = repo.__getitem__
2268
2269 def iterate():
2270 it = iter(revs)
2271 stopiteration = False
2272 for windowsize in increasingwindows():
2273 nrevs = []
2274 for i in pycompat.xrange(windowsize):
2275 rev = next(it, None)
2276 if rev is None:
2277 stopiteration = True
2278 break
2279 nrevs.append(rev)
2280 for rev in sorted(nrevs):
2281 ctx = change(rev)
2282 prepare(ctx, makefilematcher(ctx))
2283 for rev in nrevs:
2284 yield change(rev)
2285
2286 if stopiteration:
2287 break
2288
2289 return iterate()
2290
2291
2292 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts): 2243 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts):
2293 bad = [] 2244 bad = []
2294 2245
2295 badfn = lambda x, y: bad.append(x) or match.bad(x, y) 2246 badfn = lambda x, y: bad.append(x) or match.bad(x, y)
2296 names = [] 2247 names = []