mercurial/cmdutil.py
changeset 9662 f3d60543924f
parent 9656 2ae3758526d8
child 9664 2a4a0dc4fb85
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')