Mercurial > public > mercurial-scm > hg
comparison mercurial/cmdutil.py @ 9667:8743f2e1bc54
merge changes from mpm
author | Dirkjan Ochtman <dirkjan@ochtman.nl> |
---|---|
date | Fri, 30 Oct 2009 09:53:39 +0100 |
parents | 71e081b88f3e 1de5ebfa5585 |
children | 2c24471d478c |
comparison
equal
deleted
inserted
replaced
9666:71e081b88f3e | 9667:8743f2e1bc54 |
---|---|
1020 if tmpl: t.use_template(tmpl) | 1020 if tmpl: t.use_template(tmpl) |
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 | |
1025 df = util.matchdate(date) | 1026 df = util.matchdate(date) |
1026 m = matchall(repo) | 1027 m = matchall(repo) |
1027 results = {} | 1028 results = {} |
1028 for st, ctx, fns in walkchangerevs(ui, repo, m, {'rev': None}): | 1029 |
1030 def prep(ctx, fns): | |
1031 d = ctx.date() | |
1032 if df(d[0]): | |
1033 results[rev] = d | |
1034 | |
1035 for ctx in walkchangerevs(repo, m, {'rev': None}, prep): | |
1029 rev = ctx.rev() | 1036 rev = ctx.rev() |
1030 if st == 'add': | 1037 if rev in results: |
1031 d = ctx.date() | 1038 ui.status(_("Found revision %s from %s\n") % |
1032 if df(d[0]): | 1039 (rev, util.datestr(results[rev]))) |
1033 results[rev] = d | 1040 return str(rev) |
1034 elif st == 'iter': | |
1035 if rev in results: | |
1036 ui.status(_("Found revision %s from %s\n") % | |
1037 (rev, util.datestr(results[rev]))) | |
1038 return str(rev) | |
1039 | 1041 |
1040 raise util.Abort(_("revision matching date not found")) | 1042 raise util.Abort(_("revision matching date not found")) |
1041 | 1043 |
1042 def walkchangerevs(ui, repo, match, opts): | 1044 def walkchangerevs(repo, match, opts, prepare): |
1043 '''Iterate over files and the revs in which they changed. | 1045 '''Iterate over files and the revs in which they changed. |
1044 | 1046 |
1045 Callers most commonly need to iterate backwards over the history | 1047 Callers most commonly need to iterate backwards over the history |
1046 in which they are interested. Doing so has awful (quadratic-looking) | 1048 in which they are interested. Doing so has awful (quadratic-looking) |
1047 performance, so we use iterators in a "windowed" way. | 1049 performance, so we use iterators in a "windowed" way. |
1048 | 1050 |
1049 We walk a window of revisions in the desired order. Within the | 1051 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 | 1052 window, we first walk forwards to gather data, then in the desired |
1051 order (usually backwards) to display it. | 1053 order (usually backwards) to display it. |
1052 | 1054 |
1053 This function returns an iterator. The iterator yields 3-tuples. | 1055 This function returns an iterator yielding contexts. Before |
1054 They will be of one of the following forms: | 1056 yielding each context, the iterator will first call the prepare |
1055 | 1057 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 | 1058 |
1063 def increasing_windows(start, end, windowsize=8, sizelimit=512): | 1059 def increasing_windows(start, end, windowsize=8, sizelimit=512): |
1064 if start < end: | 1060 if start < end: |
1065 while start < end: | 1061 while start < end: |
1066 yield start, min(windowsize, end-start) | 1062 yield start, min(windowsize, end-start) |
1091 | 1087 |
1092 if not slowpath and not match.files(): | 1088 if not slowpath and not match.files(): |
1093 # No files, no patterns. Display all revs. | 1089 # No files, no patterns. Display all revs. |
1094 wanted = set(revs) | 1090 wanted = set(revs) |
1095 copies = [] | 1091 copies = [] |
1092 | |
1096 if not slowpath: | 1093 if not slowpath: |
1097 # Only files, no patterns. Check the history of each file. | 1094 # Only files, no patterns. Check the history of each file. |
1098 def filerevgen(filelog, node): | 1095 def filerevgen(filelog, node): |
1099 cl_count = len(repo) | 1096 cl_count = len(repo) |
1100 if node is None: | 1097 if node is None: |
1127 if follow: | 1124 if follow: |
1128 raise util.Abort(_('cannot follow nonexistent file: "%s"') % file_) | 1125 raise util.Abort(_('cannot follow nonexistent file: "%s"') % file_) |
1129 slowpath = True | 1126 slowpath = True |
1130 break | 1127 break |
1131 else: | 1128 else: |
1132 ui.warn(_('%s:%s copy source revision cannot be found!\n') | |
1133 % (file_, short(node))) | |
1134 continue | 1129 continue |
1135 for rev, copied in filerevgen(filelog, node): | 1130 for rev, copied in filerevgen(filelog, node): |
1136 if rev <= maxrev: | 1131 if rev <= maxrev: |
1137 if rev < minrev: | 1132 if rev < minrev: |
1138 break | 1133 break |
1213 else: | 1208 else: |
1214 def want(rev): | 1209 def want(rev): |
1215 return rev in wanted | 1210 return rev in wanted |
1216 | 1211 |
1217 for i, window in increasing_windows(0, len(revs)): | 1212 for i, window in increasing_windows(0, len(revs)): |
1213 change = util.cachefunc(repo.changectx) | |
1218 nrevs = [rev for rev in revs[i:i+window] if want(rev)] | 1214 nrevs = [rev for rev in revs[i:i+window] if want(rev)] |
1219 for rev in sorted(nrevs): | 1215 for rev in sorted(nrevs): |
1220 fns = fncache.get(rev) | 1216 fns = fncache.get(rev) |
1221 ctx = change(rev) | 1217 ctx = change(rev) |
1222 if not fns: | 1218 if not fns: |
1223 def fns_generator(): | 1219 def fns_generator(): |
1224 for f in ctx.files(): | 1220 for f in ctx.files(): |
1225 if match(f): | 1221 if match(f): |
1226 yield f | 1222 yield f |
1227 fns = fns_generator() | 1223 fns = fns_generator() |
1228 yield 'add', ctx, fns | 1224 prepare(ctx, fns) |
1229 for rev in nrevs: | 1225 for rev in nrevs: |
1230 yield 'iter', change(rev), None | 1226 yield change(rev) |
1231 return iterate() | 1227 return iterate() |
1232 | 1228 |
1233 def commit(ui, repo, commitfunc, pats, opts): | 1229 def commit(ui, repo, commitfunc, pats, opts): |
1234 '''commit the specified files or all outstanding changes''' | 1230 '''commit the specified files or all outstanding changes''' |
1235 date = opts.get('date') | 1231 date = opts.get('date') |