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') |