Mercurial > hg
comparison mercurial/scmutil.py @ 45720:508dfd1c18df
scmutil: move walkchangerevs() from cmdutil
It's no longer a command-level function, but a pure helper to walk revisions
in a windowed way. This change will help eliminate reverse dependency of
revset.py -> grep.py -> cmdutil.py in future patches.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 04 Oct 2020 13:17:57 +0900 |
parents | d2e1dcd4490d |
children | 8f07f5a9c3de |
comparison
equal
deleted
inserted
replaced
45719:c10c87c8fe79 | 45720:508dfd1c18df |
---|---|
758 spec = revsetlang.formatspec(b'%d', spec) | 758 spec = revsetlang.formatspec(b'%d', spec) |
759 allspecs.append(spec) | 759 allspecs.append(spec) |
760 return repo.anyrevs(allspecs, user=True, localalias=localalias) | 760 return repo.anyrevs(allspecs, user=True, localalias=localalias) |
761 | 761 |
762 | 762 |
763 def increasingwindows(windowsize=8, sizelimit=512): | |
764 while True: | |
765 yield windowsize | |
766 if windowsize < sizelimit: | |
767 windowsize *= 2 | |
768 | |
769 | |
770 def walkchangerevs(repo, revs, makefilematcher, prepare): | |
771 '''Iterate over files and the revs in a "windowed" way. | |
772 | |
773 Callers most commonly need to iterate backwards over the history | |
774 in which they are interested. Doing so has awful (quadratic-looking) | |
775 performance, so we use iterators in a "windowed" way. | |
776 | |
777 We walk a window of revisions in the desired order. Within the | |
778 window, we first walk forwards to gather data, then in the desired | |
779 order (usually backwards) to display it. | |
780 | |
781 This function returns an iterator yielding contexts. Before | |
782 yielding each context, the iterator will first call the prepare | |
783 function on each context in the window in forward order.''' | |
784 | |
785 if not revs: | |
786 return [] | |
787 change = repo.__getitem__ | |
788 | |
789 def iterate(): | |
790 it = iter(revs) | |
791 stopiteration = False | |
792 for windowsize in increasingwindows(): | |
793 nrevs = [] | |
794 for i in pycompat.xrange(windowsize): | |
795 rev = next(it, None) | |
796 if rev is None: | |
797 stopiteration = True | |
798 break | |
799 nrevs.append(rev) | |
800 for rev in sorted(nrevs): | |
801 ctx = change(rev) | |
802 prepare(ctx, makefilematcher(ctx)) | |
803 for rev in nrevs: | |
804 yield change(rev) | |
805 | |
806 if stopiteration: | |
807 break | |
808 | |
809 return iterate() | |
810 | |
811 | |
763 def meaningfulparents(repo, ctx): | 812 def meaningfulparents(repo, ctx): |
764 """Return list of meaningful (or all if debug) parentrevs for rev. | 813 """Return list of meaningful (or all if debug) parentrevs for rev. |
765 | 814 |
766 For merges (two non-nullrev revisions) both parents are meaningful. | 815 For merges (two non-nullrev revisions) both parents are meaningful. |
767 Otherwise the first parent revision is considered meaningful if it | 816 Otherwise the first parent revision is considered meaningful if it |