Show More
@@ -502,6 +502,32 b' class headerlessfixup(object):' | |||||
502 | return readexactly(self._fh, n) |
|
502 | return readexactly(self._fh, n) | |
503 |
|
503 | |||
504 | @attr.s(slots=True, frozen=True) |
|
504 | @attr.s(slots=True, frozen=True) | |
|
505 | class revisiondeltarequest(object): | |||
|
506 | """Describes a request to construct a revision delta. | |||
|
507 | ||||
|
508 | Instances are converted into ``revisiondelta`` later. | |||
|
509 | """ | |||
|
510 | # Revision whose delta will be generated. | |||
|
511 | node = attr.ib() | |||
|
512 | ||||
|
513 | # Linknode value. | |||
|
514 | linknode = attr.ib() | |||
|
515 | ||||
|
516 | # Parent revisions to record in ``revisiondelta`` instance. | |||
|
517 | p1node = attr.ib() | |||
|
518 | p2node = attr.ib() | |||
|
519 | ||||
|
520 | # Base revision that delta should be generated against. If nullrev, | |||
|
521 | # the full revision data should be populated. If None, the delta | |||
|
522 | # may be generated against any base revision that is an ancestor of | |||
|
523 | # this revision. If any other numeric value, the delta should be | |||
|
524 | # produced against that revision. | |||
|
525 | baserev = attr.ib() | |||
|
526 | ||||
|
527 | # Whether this should be marked as an ellipsis revision. | |||
|
528 | ellipsis = attr.ib(default=False) | |||
|
529 | ||||
|
530 | @attr.s(slots=True, frozen=True) | |||
505 | class revisiondelta(object): |
|
531 | class revisiondelta(object): | |
506 | """Describes a delta entry in a changegroup. |
|
532 | """Describes a delta entry in a changegroup. | |
507 |
|
533 | |||
@@ -587,14 +613,21 b' def _sortnodesellipsis(store, nodes, cl,' | |||||
587 | key = lambda n: cl.rev(lookup(n)) |
|
613 | key = lambda n: cl.rev(lookup(n)) | |
588 | return [store.rev(n) for n in sorted(nodes, key=key)] |
|
614 | return [store.rev(n) for n in sorted(nodes, key=key)] | |
589 |
|
615 | |||
590 | def _revisiondeltanormal(store, rev, prev, linknode, forcedeltaparentprev): |
|
616 | def _handlerevisiondeltarequest(store, request, prev): | |
591 | """Construct a revision delta for non-ellipses changegroup generation.""" |
|
617 | """Obtain a revisiondelta from a revisiondeltarequest""" | |
592 | node = store.node(rev) |
|
618 | ||
|
619 | node = request.node | |||
|
620 | rev = store.rev(node) | |||
|
621 | ||||
|
622 | # Requesting a full revision. | |||
|
623 | if request.baserev == nullrev: | |||
|
624 | base = nullrev | |||
|
625 | # Requesting an explicit revision. | |||
|
626 | elif request.baserev is not None: | |||
|
627 | base = request.baserev | |||
|
628 | # Allowing us to choose. | |||
|
629 | else: | |||
593 | p1, p2 = store.parentrevs(rev) |
|
630 | p1, p2 = store.parentrevs(rev) | |
594 |
|
||||
595 | if forcedeltaparentprev: |
|
|||
596 | base = prev |
|
|||
597 | else: |
|
|||
598 | dp = store.deltaparent(rev) |
|
631 | dp = store.deltaparent(rev) | |
599 |
|
632 | |||
600 | if dp == nullrev and store.storedeltachains: |
|
633 | if dp == nullrev and store.storedeltachains: | |
@@ -637,21 +670,21 b' def _revisiondeltanormal(store, rev, pre' | |||||
637 | else: |
|
670 | else: | |
638 | delta = store.revdiff(base, rev) |
|
671 | delta = store.revdiff(base, rev) | |
639 |
|
672 | |||
640 | p1n, p2n = store.parents(node) |
|
673 | extraflags = revlog.REVIDX_ELLIPSIS if request.ellipsis else 0 | |
641 |
|
674 | |||
642 | return revisiondelta( |
|
675 | return revisiondelta( | |
643 | node=node, |
|
676 | node=node, | |
644 | p1node=p1n, |
|
677 | p1node=request.p1node, | |
645 | p2node=p2n, |
|
678 | p2node=request.p2node, | |
|
679 | linknode=request.linknode, | |||
646 | basenode=store.node(base), |
|
680 | basenode=store.node(base), | |
647 | linknode=linknode, |
|
681 | flags=store.flags(rev) | extraflags, | |
648 | flags=store.flags(rev), |
|
|||
649 | baserevisionsize=baserevisionsize, |
|
682 | baserevisionsize=baserevisionsize, | |
650 | revision=revision, |
|
683 | revision=revision, | |
651 | delta=delta, |
|
684 | delta=delta, | |
652 | ) |
|
685 | ) | |
653 |
|
686 | |||
654 |
def _ |
|
687 | def _makenarrowdeltarequest(cl, store, ischangelog, rev, node, linkrev, | |
655 | linknode, clrevtolocalrev, fullclnodes, |
|
688 | linknode, clrevtolocalrev, fullclnodes, | |
656 | precomputedellipsis): |
|
689 | precomputedellipsis): | |
657 | linkparents = precomputedellipsis[linkrev] |
|
690 | linkparents = precomputedellipsis[linkrev] | |
@@ -726,23 +759,16 b' def _revisiondeltanarrow(cl, store, isch' | |||||
726 | else: |
|
759 | else: | |
727 | p1, p2 = sorted(local(p) for p in linkparents) |
|
760 | p1, p2 = sorted(local(p) for p in linkparents) | |
728 |
|
761 | |||
729 | n = store.node(rev) |
|
762 | p1node, p2node = store.node(p1), store.node(p2) | |
730 | p1n, p2n = store.node(p1), store.node(p2) |
|
|||
731 | flags = store.flags(rev) |
|
|||
732 | flags |= revlog.REVIDX_ELLIPSIS |
|
|||
733 |
|
763 | |||
734 | # TODO: try and actually send deltas for ellipsis data blocks |
|
764 | # TODO: try and actually send deltas for ellipsis data blocks | |
735 |
|
765 | return revisiondeltarequest( | ||
736 | return revisiondelta( |
|
766 | node=node, | |
737 | node=n, |
|
767 | p1node=p1node, | |
738 |
p |
|
768 | p2node=p2node, | |
739 | p2node=p2n, |
|
|||
740 | basenode=nullid, |
|
|||
741 | linknode=linknode, |
|
769 | linknode=linknode, | |
742 | flags=flags, |
|
770 | baserev=nullrev, | |
743 | baserevisionsize=None, |
|
771 | ellipsis=True, | |
744 | revision=store.revision(n), |
|
|||
745 | delta=None, |
|
|||
746 | ) |
|
772 | ) | |
747 |
|
773 | |||
748 | def deltagroup(repo, revs, store, ischangelog, lookup, forcedeltaparentprev, |
|
774 | def deltagroup(repo, revs, store, ischangelog, lookup, forcedeltaparentprev, | |
@@ -759,25 +785,32 b' def deltagroup(repo, revs, store, ischan' | |||||
759 | if not revs: |
|
785 | if not revs: | |
760 | return |
|
786 | return | |
761 |
|
787 | |||
|
788 | # We perform two passes over the revisions whose data we will emit. | |||
|
789 | # | |||
|
790 | # In the first pass, we obtain information about the deltas that will | |||
|
791 | # be generated. This involves computing linknodes and adjusting the | |||
|
792 | # request to take shallow fetching into account. The end result of | |||
|
793 | # this pass is a list of "request" objects stating which deltas | |||
|
794 | # to obtain. | |||
|
795 | # | |||
|
796 | # The second pass is simply resolving the requested deltas. | |||
|
797 | ||||
762 | cl = repo.changelog |
|
798 | cl = repo.changelog | |
763 |
|
799 | |||
|
800 | # In the first pass, collect info about the deltas we'll be | |||
|
801 | # generating. | |||
|
802 | requests = [] | |||
|
803 | ||||
764 | # Add the parent of the first rev. |
|
804 | # Add the parent of the first rev. | |
765 | revs.insert(0, store.parentrevs(revs[0])[0]) |
|
805 | revs.insert(0, store.parentrevs(revs[0])[0]) | |
766 |
|
806 | |||
767 | # build deltas |
|
|||
768 | progress = None |
|
|||
769 | if units is not None: |
|
|||
770 | progress = repo.ui.makeprogress(_('bundling'), unit=units, |
|
|||
771 | total=(len(revs) - 1)) |
|
|||
772 |
|
||||
773 | for i in pycompat.xrange(len(revs) - 1): |
|
807 | for i in pycompat.xrange(len(revs) - 1): | |
774 | if progress: |
|
|||
775 | progress.update(i + 1) |
|
|||
776 |
|
||||
777 | prev = revs[i] |
|
808 | prev = revs[i] | |
778 | curr = revs[i + 1] |
|
809 | curr = revs[i + 1] | |
779 |
|
810 | |||
780 |
|
|
811 | node = store.node(curr) | |
|
812 | linknode = lookup(node) | |||
|
813 | p1node, p2node = store.parents(node) | |||
781 |
|
814 | |||
782 | if ellipses: |
|
815 | if ellipses: | |
783 | linkrev = cl.rev(linknode) |
|
816 | linkrev = cl.rev(linknode) | |
@@ -786,22 +819,48 b' def deltagroup(repo, revs, store, ischan' | |||||
786 | # This is a node to send in full, because the changeset it |
|
819 | # This is a node to send in full, because the changeset it | |
787 | # corresponds to was a full changeset. |
|
820 | # corresponds to was a full changeset. | |
788 | if linknode in fullclnodes: |
|
821 | if linknode in fullclnodes: | |
789 | delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
822 | requests.append(revisiondeltarequest( | |
790 | forcedeltaparentprev) |
|
823 | node=node, | |
|
824 | p1node=p1node, | |||
|
825 | p2node=p2node, | |||
|
826 | linknode=linknode, | |||
|
827 | baserev=None, | |||
|
828 | )) | |||
|
829 | ||||
791 | elif linkrev not in precomputedellipsis: |
|
830 | elif linkrev not in precomputedellipsis: | |
792 |
|
|
831 | pass | |
793 | else: |
|
832 | else: | |
794 | delta = _revisiondeltanarrow( |
|
833 | requests.append(_makenarrowdeltarequest( | |
795 | cl, store, ischangelog, curr, linkrev, linknode, |
|
834 | cl, store, ischangelog, curr, node, linkrev, linknode, | |
796 | clrevtolocalrev, fullclnodes, |
|
835 | clrevtolocalrev, fullclnodes, | |
797 | precomputedellipsis) |
|
836 | precomputedellipsis)) | |
798 | else: |
|
837 | else: | |
799 | delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
838 | requests.append(revisiondeltarequest( | |
800 | forcedeltaparentprev) |
|
839 | node=node, | |
|
840 | p1node=p1node, | |||
|
841 | p2node=p2node, | |||
|
842 | linknode=linknode, | |||
|
843 | baserev=prev if forcedeltaparentprev else None, | |||
|
844 | )) | |||
801 |
|
845 | |||
802 | if delta: |
|
846 | # We expect the first pass to be fast, so we only engage the progress | |
|
847 | # meter for constructing the revision deltas. | |||
|
848 | progress = None | |||
|
849 | if units is not None: | |||
|
850 | progress = repo.ui.makeprogress(_('bundling'), unit=units, | |||
|
851 | total=len(requests)) | |||
|
852 | ||||
|
853 | prevrev = revs[0] | |||
|
854 | for i, request in enumerate(requests): | |||
|
855 | if progress: | |||
|
856 | progress.update(i + 1) | |||
|
857 | ||||
|
858 | delta = _handlerevisiondeltarequest(store, request, prevrev) | |||
|
859 | ||||
803 |
|
|
860 | yield delta | |
804 |
|
861 | |||
|
862 | prevrev = store.rev(request.node) | |||
|
863 | ||||
805 | if progress: |
|
864 | if progress: | |
806 | progress.complete() |
|
865 | progress.complete() | |
807 |
|
866 |
General Comments 0
You need to be logged in to leave comments.
Login now