mercurial/cmdutil.py
changeset 20553 86cefb15e7b5
parent 20500 ce3f3082ec45
child 20571 d4893e64f300
equal deleted inserted replaced
20552:0e99a66eb7bc 20553:86cefb15e7b5
  1131                       (rev, util.datestr(results[rev])))
  1131                       (rev, util.datestr(results[rev])))
  1132             return str(rev)
  1132             return str(rev)
  1133 
  1133 
  1134     raise util.Abort(_("revision matching date not found"))
  1134     raise util.Abort(_("revision matching date not found"))
  1135 
  1135 
  1136 def increasingwindows(start, end, windowsize=8, sizelimit=512):
  1136 def increasingwindows(windowsize=8, sizelimit=512):
  1137     if start < end:
  1137     while True:
  1138         while start < end:
  1138         yield windowsize
  1139             yield start, min(windowsize, end - start)
  1139         if windowsize < sizelimit:
  1140             start += windowsize
  1140             windowsize *= 2
  1141             if windowsize < sizelimit:
       
  1142                 windowsize *= 2
       
  1143     else:
       
  1144         while start > end:
       
  1145             yield start, min(windowsize, start - end - 1)
       
  1146             start -= windowsize
       
  1147             if windowsize < sizelimit:
       
  1148                 windowsize *= 2
       
  1149 
  1141 
  1150 class FileWalkError(Exception):
  1142 class FileWalkError(Exception):
  1151     pass
  1143     pass
  1152 
  1144 
  1153 def walkfilerevs(repo, match, follow, revs, fncache):
  1145 def walkfilerevs(repo, match, follow, revs, fncache):
  1276         return []
  1268         return []
  1277     wanted = set()
  1269     wanted = set()
  1278     slowpath = match.anypats() or (match.files() and opts.get('removed'))
  1270     slowpath = match.anypats() or (match.files() and opts.get('removed'))
  1279     fncache = {}
  1271     fncache = {}
  1280     change = repo.changectx
  1272     change = repo.changectx
  1281     revs = revset.baseset(revs)
       
  1282 
  1273 
  1283     # First step is to fill wanted, the set of revisions that we want to yield.
  1274     # First step is to fill wanted, the set of revisions that we want to yield.
  1284     # When it does not induce extra cost, we also fill fncache for revisions in
  1275     # When it does not induce extra cost, we also fill fncache for revisions in
  1285     # wanted: a cache of filenames that were changed (ctx.files()) and that
  1276     # wanted: a cache of filenames that were changed (ctx.files()) and that
  1286     # match the file filtering conditions.
  1277     # match the file filtering conditions.
  1287 
  1278 
  1288     if not slowpath and not match.files():
  1279     if not slowpath and not match.files():
  1289         # No files, no patterns.  Display all revs.
  1280         # No files, no patterns.  Display all revs.
  1290         wanted = set(revs)
  1281         wanted = revs
  1291 
  1282 
  1292     if not slowpath and match.files():
  1283     if not slowpath and match.files():
  1293         # We only have to read through the filelog to find wanted revisions
  1284         # We only have to read through the filelog to find wanted revisions
  1294 
  1285 
  1295         try:
  1286         try:
  1387         rev = repo[rev].rev()
  1378         rev = repo[rev].rev()
  1388         ff = followfilter()
  1379         ff = followfilter()
  1389         stop = min(revs[0], revs[-1])
  1380         stop = min(revs[0], revs[-1])
  1390         for x in xrange(rev, stop - 1, -1):
  1381         for x in xrange(rev, stop - 1, -1):
  1391             if ff.match(x):
  1382             if ff.match(x):
  1392                 wanted.discard(x)
  1383                 wanted = wanted - [x]
  1393 
       
  1394     # Choose a small initial window if we will probably only visit a
       
  1395     # few commits.
       
  1396     limit = loglimit(opts)
       
  1397     windowsize = 8
       
  1398     if limit:
       
  1399         windowsize = min(limit, windowsize)
       
  1400 
  1384 
  1401     # Now that wanted is correctly initialized, we can iterate over the
  1385     # Now that wanted is correctly initialized, we can iterate over the
  1402     # revision range, yielding only revisions in wanted.
  1386     # revision range, yielding only revisions in wanted.
  1403     def iterate():
  1387     def iterate():
  1404         if follow and not match.files():
  1388         if follow and not match.files():
  1407                 return ff.match(rev) and rev in wanted
  1391                 return ff.match(rev) and rev in wanted
  1408         else:
  1392         else:
  1409             def want(rev):
  1393             def want(rev):
  1410                 return rev in wanted
  1394                 return rev in wanted
  1411 
  1395 
  1412         for i, window in increasingwindows(0, len(revs), windowsize):
  1396         it = iter(revs)
  1413             nrevs = [rev for rev in revs[i:i + window] if want(rev)]
  1397         stopiteration = False
       
  1398         for windowsize in increasingwindows():
       
  1399             nrevs = []
       
  1400             for i in xrange(windowsize):
       
  1401                 try:
       
  1402                     rev = it.next()
       
  1403                     if want(rev):
       
  1404                         nrevs.append(rev)
       
  1405                 except (StopIteration):
       
  1406                     stopiteration = True
       
  1407                     break
  1414             for rev in sorted(nrevs):
  1408             for rev in sorted(nrevs):
  1415                 fns = fncache.get(rev)
  1409                 fns = fncache.get(rev)
  1416                 ctx = change(rev)
  1410                 ctx = change(rev)
  1417                 if not fns:
  1411                 if not fns:
  1418                     def fns_generator():
  1412                     def fns_generator():
  1421                                 yield f
  1415                                 yield f
  1422                     fns = fns_generator()
  1416                     fns = fns_generator()
  1423                 prepare(ctx, fns)
  1417                 prepare(ctx, fns)
  1424             for rev in nrevs:
  1418             for rev in nrevs:
  1425                 yield change(rev)
  1419                 yield change(rev)
       
  1420 
       
  1421             if stopiteration:
       
  1422                 break
       
  1423 
  1426     return iterate()
  1424     return iterate()
  1427 
  1425 
  1428 def _makegraphfilematcher(repo, pats, followfirst):
  1426 def _makegraphfilematcher(repo, pats, followfirst):
  1429     # When displaying a revision with --patch --follow FILE, we have
  1427     # When displaying a revision with --patch --follow FILE, we have
  1430     # to know which file of the revision must be diffed. With
  1428     # to know which file of the revision must be diffed. With