comparison mercurial/cmdutil.py @ 9662:f3d60543924f

walkchangerevs: move 'add' to callback Now walkchangerevs is a simple iterator over contexts
author Matt Mackall <mpm@selenic.com>
date Thu, 29 Oct 2009 17:07:51 -0500
parents 2ae3758526d8
children 2a4a0dc4fb85
comparison
equal deleted inserted replaced
9661:c4f6c02e33c4 9662:f3d60543924f
1021 return t 1021 return t
1022 1022
1023 def finddate(ui, repo, date): 1023 def finddate(ui, repo, date):
1024 """Find the tipmost changeset that matches the given date spec""" 1024 """Find the tipmost changeset that matches the given date spec"""
1025 df = util.matchdate(date) 1025 df = util.matchdate(date)
1026 get = util.cachefunc(lambda r: repo[r])
1027 m = matchall(repo) 1026 m = matchall(repo)
1028 results = {} 1027 results = {}
1029 for st, rev, fns in walkchangerevs(ui, repo, m, get, {'rev':None}): 1028
1030 if st == 'add': 1029 def prep(ctx, fns):
1031 d = get(rev).date() 1030 d = ctx.date()
1032 if df(d[0]): 1031 if df(d[0]):
1033 results[rev] = d 1032 results[rev] = d
1034 elif st == 'iter': 1033
1035 if rev in results: 1034 for ctx in walkchangerevs(ui, repo, m, {'rev':None}, prep):
1036 ui.status(_("Found revision %s from %s\n") % 1035 rev = ctx.rev()
1037 (rev, util.datestr(results[rev]))) 1036 if rev in results:
1038 return str(rev) 1037 ui.status(_("Found revision %s from %s\n") %
1038 (rev, util.datestr(results[rev])))
1039 return str(rev)
1039 1040
1040 raise util.Abort(_("revision matching date not found")) 1041 raise util.Abort(_("revision matching date not found"))
1041 1042
1042 def walkchangerevs(ui, repo, match, opts): 1043 def walkchangerevs(ui, repo, match, opts, prepare):
1043 '''Iterate over files and the revs in which they changed. 1044 '''Iterate over files and the revs in which they changed.
1044 1045
1045 Callers most commonly need to iterate backwards over the history 1046 Callers most commonly need to iterate backwards over the history
1046 in which they are interested. Doing so has awful (quadratic-looking) 1047 in which they are interested. Doing so has awful (quadratic-looking)
1047 performance, so we use iterators in a "windowed" way. 1048 performance, so we use iterators in a "windowed" way.
1048 1049
1049 We walk a window of revisions in the desired order. Within the 1050 We walk a window of revisions in the desired order. Within the
1050 window, we first walk forwards to gather data, then in the desired 1051 window, we first walk forwards to gather data, then in the desired
1051 order (usually backwards) to display it. 1052 order (usually backwards) to display it.
1052 1053
1053 This function returns an iterator. The iterator yields 3-tuples. 1054 This function returns an iterator yielding contexts. Before
1054 They will be of one of the following forms: 1055 yielding each context, the iterator will first call the prepare
1055 1056 function on each context in the window in forward order.'''
1056 "add", rev, fns: out-of-order traversal of the given filenames
1057 fns, which changed during revision rev - use to gather data for
1058 possible display
1059
1060 "iter", rev, None: in-order traversal of the revs earlier iterated
1061 over with "add" - use to display data'''
1062 1057
1063 def increasing_windows(start, end, windowsize=8, sizelimit=512): 1058 def increasing_windows(start, end, windowsize=8, sizelimit=512):
1064 if start < end: 1059 if start < end:
1065 while start < end: 1060 while start < end:
1066 yield start, min(windowsize, end-start) 1061 yield start, min(windowsize, end-start)
1223 def fns_generator(): 1218 def fns_generator():
1224 for f in ctx.files(): 1219 for f in ctx.files():
1225 if match(f): 1220 if match(f):
1226 yield f 1221 yield f
1227 fns = fns_generator() 1222 fns = fns_generator()
1228 yield 'add', ctx, fns 1223 prepare(ctx, fns)
1229 for rev in nrevs: 1224 for rev in nrevs:
1230 yield 'iter', change(rev), None 1225 yield change(rev)
1231 return iterate() 1226 return iterate()
1232 1227
1233 def commit(ui, repo, commitfunc, pats, opts): 1228 def commit(ui, repo, commitfunc, pats, opts):
1234 '''commit the specified files or all outstanding changes''' 1229 '''commit the specified files or all outstanding changes'''
1235 date = opts.get('date') 1230 date = opts.get('date')