679 linknode=linknode, |
679 linknode=linknode, |
680 flags=flags, |
680 flags=flags, |
681 deltachunks=(diffheader, data), |
681 deltachunks=(diffheader, data), |
682 ) |
682 ) |
683 |
683 |
|
684 def deltagroup(repo, revs, store, ischangelog, lookup, deltaparentfn, |
|
685 deltaheaderfn, units=None, |
|
686 ellipses=False, clrevtolocalrev=None, fullclnodes=None, |
|
687 precomputedellipsis=None): |
|
688 """Calculate a delta group, yielding a sequence of changegroup chunks |
|
689 (strings). |
|
690 |
|
691 Given a list of changeset revs, return a set of deltas and |
|
692 metadata corresponding to nodes. The first delta is |
|
693 first parent(nodelist[0]) -> nodelist[0], the receiver is |
|
694 guaranteed to have this parent as it has all history before |
|
695 these changesets. In the case firstparent is nullrev the |
|
696 changegroup starts with a full revision. |
|
697 |
|
698 If units is not None, progress detail will be generated, units specifies |
|
699 the type of revlog that is touched (changelog, manifest, etc.). |
|
700 """ |
|
701 # if we don't have any revisions touched by these changesets, bail |
|
702 if len(revs) == 0: |
|
703 yield closechunk() |
|
704 return |
|
705 |
|
706 cl = repo.changelog |
|
707 |
|
708 # add the parent of the first rev |
|
709 p = store.parentrevs(revs[0])[0] |
|
710 revs.insert(0, p) |
|
711 |
|
712 # build deltas |
|
713 progress = None |
|
714 if units is not None: |
|
715 progress = repo.ui.makeprogress(_('bundling'), unit=units, |
|
716 total=(len(revs) - 1)) |
|
717 for r in pycompat.xrange(len(revs) - 1): |
|
718 if progress: |
|
719 progress.update(r + 1) |
|
720 prev, curr = revs[r], revs[r + 1] |
|
721 linknode = lookup(store.node(curr)) |
|
722 |
|
723 if ellipses: |
|
724 linkrev = cl.rev(linknode) |
|
725 clrevtolocalrev[linkrev] = curr |
|
726 |
|
727 # This is a node to send in full, because the changeset it |
|
728 # corresponds to was a full changeset. |
|
729 if linknode in fullclnodes: |
|
730 delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
731 deltaparentfn) |
|
732 elif linkrev not in precomputedellipsis: |
|
733 delta = None |
|
734 else: |
|
735 delta = _revisiondeltanarrow( |
|
736 cl, store, ischangelog, curr, linkrev, linknode, |
|
737 clrevtolocalrev, fullclnodes, |
|
738 precomputedellipsis) |
|
739 else: |
|
740 delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
741 deltaparentfn) |
|
742 |
|
743 if not delta: |
|
744 continue |
|
745 |
|
746 meta = deltaheaderfn(delta) |
|
747 l = len(meta) + sum(len(x) for x in delta.deltachunks) |
|
748 yield chunkheader(l) |
|
749 yield meta |
|
750 for x in delta.deltachunks: |
|
751 yield x |
|
752 |
|
753 if progress: |
|
754 progress.complete() |
|
755 |
|
756 yield closechunk() |
|
757 |
684 class cgpacker(object): |
758 class cgpacker(object): |
685 def __init__(self, repo, filematcher, version, allowreorder, |
759 def __init__(self, repo, filematcher, version, allowreorder, |
686 deltaparentfn, builddeltaheader, manifestsend, |
760 deltaparentfn, builddeltaheader, manifestsend, |
687 bundlecaps=None, ellipses=False, |
761 bundlecaps=None, ellipses=False, |
688 shallow=False, ellipsisroots=None, fullnodes=None): |
762 shallow=False, ellipsisroots=None, fullnodes=None): |
748 |
822 |
749 if self._repo.ui.verbose and not self._repo.ui.debugflag: |
823 if self._repo.ui.verbose and not self._repo.ui.debugflag: |
750 self._verbosenote = self._repo.ui.note |
824 self._verbosenote = self._repo.ui.note |
751 else: |
825 else: |
752 self._verbosenote = lambda s: None |
826 self._verbosenote = lambda s: None |
753 |
|
754 def group(self, repo, revs, store, ischangelog, lookup, deltaparentfn, |
|
755 deltaheaderfn, units=None, |
|
756 ellipses=False, clrevtolocalrev=None, fullclnodes=None, |
|
757 precomputedellipsis=None): |
|
758 """Calculate a delta group, yielding a sequence of changegroup chunks |
|
759 (strings). |
|
760 |
|
761 Given a list of changeset revs, return a set of deltas and |
|
762 metadata corresponding to nodes. The first delta is |
|
763 first parent(nodelist[0]) -> nodelist[0], the receiver is |
|
764 guaranteed to have this parent as it has all history before |
|
765 these changesets. In the case firstparent is nullrev the |
|
766 changegroup starts with a full revision. |
|
767 |
|
768 If units is not None, progress detail will be generated, units specifies |
|
769 the type of revlog that is touched (changelog, manifest, etc.). |
|
770 """ |
|
771 # if we don't have any revisions touched by these changesets, bail |
|
772 if len(revs) == 0: |
|
773 yield closechunk() |
|
774 return |
|
775 |
|
776 cl = repo.changelog |
|
777 |
|
778 # add the parent of the first rev |
|
779 p = store.parentrevs(revs[0])[0] |
|
780 revs.insert(0, p) |
|
781 |
|
782 # build deltas |
|
783 progress = None |
|
784 if units is not None: |
|
785 progress = repo.ui.makeprogress(_('bundling'), unit=units, |
|
786 total=(len(revs) - 1)) |
|
787 for r in pycompat.xrange(len(revs) - 1): |
|
788 if progress: |
|
789 progress.update(r + 1) |
|
790 prev, curr = revs[r], revs[r + 1] |
|
791 linknode = lookup(store.node(curr)) |
|
792 |
|
793 if ellipses: |
|
794 linkrev = cl.rev(linknode) |
|
795 clrevtolocalrev[linkrev] = curr |
|
796 |
|
797 # This is a node to send in full, because the changeset it |
|
798 # corresponds to was a full changeset. |
|
799 if linknode in fullclnodes: |
|
800 delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
801 deltaparentfn) |
|
802 elif linkrev not in precomputedellipsis: |
|
803 delta = None |
|
804 else: |
|
805 delta = _revisiondeltanarrow( |
|
806 cl, store, ischangelog, curr, linkrev, linknode, |
|
807 clrevtolocalrev, fullclnodes, |
|
808 precomputedellipsis) |
|
809 else: |
|
810 delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
811 deltaparentfn) |
|
812 |
|
813 if not delta: |
|
814 continue |
|
815 |
|
816 meta = deltaheaderfn(delta) |
|
817 l = len(meta) + sum(len(x) for x in delta.deltachunks) |
|
818 yield chunkheader(l) |
|
819 yield meta |
|
820 for x in delta.deltachunks: |
|
821 yield x |
|
822 |
|
823 if progress: |
|
824 progress.complete() |
|
825 |
|
826 yield closechunk() |
|
827 |
827 |
828 def generate(self, commonrevs, clnodes, fastpathlinkrev, source): |
828 def generate(self, commonrevs, clnodes, fastpathlinkrev, source): |
829 """Yield a sequence of changegroup byte chunks.""" |
829 """Yield a sequence of changegroup byte chunks.""" |
830 |
830 |
831 repo = self._repo |
831 repo = self._repo |
956 'mfs': mfs, |
956 'mfs': mfs, |
957 'changedfiles': changedfiles, |
957 'changedfiles': changedfiles, |
958 'clrevtomanifestrev': clrevtomanifestrev, |
958 'clrevtomanifestrev': clrevtomanifestrev, |
959 } |
959 } |
960 |
960 |
961 gen = self.group(self._repo, revs, cl, True, lookupcl, |
961 gen = deltagroup( |
962 self._deltaparentfn, self._builddeltaheader, |
962 self._repo, revs, cl, True, lookupcl, |
963 ellipses=self._ellipses, |
963 self._deltaparentfn, self._builddeltaheader, |
964 units=_('changesets'), |
964 ellipses=self._ellipses, |
965 clrevtolocalrev={}, |
965 units=_('changesets'), |
966 fullclnodes=self._fullclnodes, |
966 clrevtolocalrev={}, |
967 precomputedellipsis=self._precomputedellipsis) |
967 fullclnodes=self._fullclnodes, |
|
968 precomputedellipsis=self._precomputedellipsis) |
968 |
969 |
969 return state, gen |
970 return state, gen |
970 |
971 |
971 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs, |
972 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs, |
972 fnodes, source, clrevtolocalrev): |
973 fnodes, source, clrevtolocalrev): |
1051 assert self.version == b'03' |
1052 assert self.version == b'03' |
1052 chunk = _fileheader(dir) |
1053 chunk = _fileheader(dir) |
1053 size += len(chunk) |
1054 size += len(chunk) |
1054 yield chunk |
1055 yield chunk |
1055 |
1056 |
1056 it = self.group( |
1057 it = deltagroup( |
1057 self._repo, revs, store, False, lookupfn, |
1058 self._repo, revs, store, False, lookupfn, |
1058 self._deltaparentfn, self._builddeltaheader, |
1059 self._deltaparentfn, self._builddeltaheader, |
1059 ellipses=self._ellipses, |
1060 ellipses=self._ellipses, |
1060 units=_('manifests'), |
1061 units=_('manifests'), |
1061 clrevtolocalrev=clrevtolocalrev, |
1062 clrevtolocalrev=clrevtolocalrev, |
1151 progress.update(i + 1, item=fname) |
1152 progress.update(i + 1, item=fname) |
1152 h = _fileheader(fname) |
1153 h = _fileheader(fname) |
1153 size = len(h) |
1154 size = len(h) |
1154 yield h |
1155 yield h |
1155 |
1156 |
1156 it = self.group( |
1157 it = deltagroup( |
1157 self._repo, revs, filerevlog, False, lookupfilelog, |
1158 self._repo, revs, filerevlog, False, lookupfilelog, |
1158 self._deltaparentfn, self._builddeltaheader, |
1159 self._deltaparentfn, self._builddeltaheader, |
1159 ellipses=self._ellipses, |
1160 ellipses=self._ellipses, |
1160 clrevtolocalrev=clrevtolocalrev, |
1161 clrevtolocalrev=clrevtolocalrev, |
1161 fullclnodes=self._fullclnodes, |
1162 fullclnodes=self._fullclnodes, |