519 linknode = attr.ib() |
519 linknode = attr.ib() |
520 # 2 bytes of flags to apply to revision data. |
520 # 2 bytes of flags to apply to revision data. |
521 flags = attr.ib() |
521 flags = attr.ib() |
522 # Iterable of chunks holding raw delta data. |
522 # Iterable of chunks holding raw delta data. |
523 deltachunks = attr.ib() |
523 deltachunks = attr.ib() |
|
524 |
|
525 def _revisiondeltatochunks(delta, headerfn): |
|
526 """Serialize a revisiondelta to changegroup chunks.""" |
|
527 meta = headerfn(delta) |
|
528 l = len(meta) + sum(len(x) for x in delta.deltachunks) |
|
529 yield chunkheader(l) |
|
530 yield meta |
|
531 for x in delta.deltachunks: |
|
532 yield x |
524 |
533 |
525 def _sortnodesnormal(store, nodes, reorder): |
534 def _sortnodesnormal(store, nodes, reorder): |
526 """Sort nodes for changegroup generation and turn into revnums.""" |
535 """Sort nodes for changegroup generation and turn into revnums.""" |
527 # for generaldelta revlogs, we linearize the revs; this will both be |
536 # for generaldelta revlogs, we linearize the revs; this will both be |
528 # much quicker and generate a much smaller bundle |
537 # much quicker and generate a much smaller bundle |
680 flags=flags, |
689 flags=flags, |
681 deltachunks=(diffheader, data), |
690 deltachunks=(diffheader, data), |
682 ) |
691 ) |
683 |
692 |
684 def deltagroup(repo, revs, store, ischangelog, lookup, deltaparentfn, |
693 def deltagroup(repo, revs, store, ischangelog, lookup, deltaparentfn, |
685 deltaheaderfn, units=None, |
694 units=None, |
686 ellipses=False, clrevtolocalrev=None, fullclnodes=None, |
695 ellipses=False, clrevtolocalrev=None, fullclnodes=None, |
687 precomputedellipsis=None): |
696 precomputedellipsis=None): |
688 """Calculate a delta group, yielding a sequence of changegroup chunks |
697 """Calculate deltas for a set of revisions. |
689 (strings). |
698 |
690 |
699 Is a generator of ``revisiondelta`` instances. |
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 |
700 |
698 If units is not None, progress detail will be generated, units specifies |
701 If units is not None, progress detail will be generated, units specifies |
699 the type of revlog that is touched (changelog, manifest, etc.). |
702 the type of revlog that is touched (changelog, manifest, etc.). |
700 """ |
703 """ |
701 # if we don't have any revisions touched by these changesets, bail |
704 # if we don't have any revisions touched by these changesets, bail |
737 precomputedellipsis) |
740 precomputedellipsis) |
738 else: |
741 else: |
739 delta = _revisiondeltanormal(store, curr, prev, linknode, |
742 delta = _revisiondeltanormal(store, curr, prev, linknode, |
740 deltaparentfn) |
743 deltaparentfn) |
741 |
744 |
742 if not delta: |
745 if delta: |
743 continue |
746 yield delta |
744 |
|
745 meta = deltaheaderfn(delta) |
|
746 l = len(meta) + sum(len(x) for x in delta.deltachunks) |
|
747 yield chunkheader(l) |
|
748 yield meta |
|
749 for x in delta.deltachunks: |
|
750 yield x |
|
751 |
747 |
752 if progress: |
748 if progress: |
753 progress.complete() |
749 progress.complete() |
754 |
750 |
755 class cgpacker(object): |
751 class cgpacker(object): |
873 size = 0 |
870 size = 0 |
874 it = self.generatemanifests( |
871 it = self.generatemanifests( |
875 commonrevs, clrevorder, fastpathlinkrev, mfs, fnodes, source, |
872 commonrevs, clrevorder, fastpathlinkrev, mfs, fnodes, source, |
876 clstate['clrevtomanifestrev']) |
873 clstate['clrevtomanifestrev']) |
877 |
874 |
878 for dir, chunks in it: |
875 for dir, deltas in it: |
879 if dir: |
876 if dir: |
880 assert self.version == b'03' |
877 assert self.version == b'03' |
881 chunk = _fileheader(dir) |
878 chunk = _fileheader(dir) |
882 size += len(chunk) |
879 size += len(chunk) |
883 yield chunk |
880 yield chunk |
884 |
881 |
885 for chunk in chunks: |
882 for delta in deltas: |
886 size += len(chunk) |
883 chunks = _revisiondeltatochunks(delta, self._builddeltaheader) |
887 yield chunk |
884 for chunk in chunks: |
|
885 size += len(chunk) |
|
886 yield chunk |
888 |
887 |
889 close = closechunk() |
888 close = closechunk() |
890 size += len(close) |
889 size += len(close) |
891 yield close |
890 yield close |
892 |
891 |
903 |
902 |
904 it = self.generatefiles(changedfiles, commonrevs, |
903 it = self.generatefiles(changedfiles, commonrevs, |
905 source, mfdicts, fastpathlinkrev, |
904 source, mfdicts, fastpathlinkrev, |
906 fnodes, clrevs) |
905 fnodes, clrevs) |
907 |
906 |
908 for path, chunks in it: |
907 for path, deltas in it: |
909 h = _fileheader(path) |
908 h = _fileheader(path) |
910 size = len(h) |
909 size = len(h) |
911 yield h |
910 yield h |
912 |
911 |
913 for chunk in chunks: |
912 for delta in deltas: |
914 size += len(chunk) |
913 chunks = _revisiondeltatochunks(delta, self._builddeltaheader) |
915 yield chunk |
914 for chunk in chunks: |
|
915 size += len(chunk) |
|
916 yield chunk |
916 |
917 |
917 close = closechunk() |
918 close = closechunk() |
918 size += len(close) |
919 size += len(close) |
919 yield close |
920 yield close |
920 |
921 |
991 'clrevtomanifestrev': clrevtomanifestrev, |
992 'clrevtomanifestrev': clrevtomanifestrev, |
992 } |
993 } |
993 |
994 |
994 gen = deltagroup( |
995 gen = deltagroup( |
995 self._repo, revs, cl, True, lookupcl, |
996 self._repo, revs, cl, True, lookupcl, |
996 self._deltaparentfn, self._builddeltaheader, |
997 self._deltaparentfn, |
997 ellipses=self._ellipses, |
998 ellipses=self._ellipses, |
998 units=_('changesets'), |
999 units=_('changesets'), |
999 clrevtolocalrev={}, |
1000 clrevtolocalrev={}, |
1000 fullclnodes=self._fullclnodes, |
1001 fullclnodes=self._fullclnodes, |
1001 precomputedellipsis=self._precomputedellipsis) |
1002 precomputedellipsis=self._precomputedellipsis) |
1078 lookupfn) |
1079 lookupfn) |
1079 else: |
1080 else: |
1080 revs = _sortnodesnormal(store, prunednodes, |
1081 revs = _sortnodesnormal(store, prunednodes, |
1081 self._reorder) |
1082 self._reorder) |
1082 |
1083 |
1083 it = deltagroup( |
1084 deltas = deltagroup( |
1084 self._repo, revs, store, False, lookupfn, |
1085 self._repo, revs, store, False, lookupfn, |
1085 self._deltaparentfn, self._builddeltaheader, |
1086 self._deltaparentfn, |
1086 ellipses=self._ellipses, |
1087 ellipses=self._ellipses, |
1087 units=_('manifests'), |
1088 units=_('manifests'), |
1088 clrevtolocalrev=clrevtolocalrev, |
1089 clrevtolocalrev=clrevtolocalrev, |
1089 fullclnodes=self._fullclnodes, |
1090 fullclnodes=self._fullclnodes, |
1090 precomputedellipsis=self._precomputedellipsis) |
1091 precomputedellipsis=self._precomputedellipsis) |
1091 |
1092 |
1092 yield dir, it |
1093 yield dir, deltas |
1093 |
1094 |
1094 # The 'source' parameter is useful for extensions |
1095 # The 'source' parameter is useful for extensions |
1095 def generatefiles(self, changedfiles, commonrevs, source, |
1096 def generatefiles(self, changedfiles, commonrevs, source, |
1096 mfdicts, fastpathlinkrev, fnodes, clrevs): |
1097 mfdicts, fastpathlinkrev, fnodes, clrevs): |
1097 changedfiles = list(filter(self._filematcher, changedfiles)) |
1098 changedfiles = list(filter(self._filematcher, changedfiles)) |
1170 revs = _sortnodesnormal(filerevlog, filenodes, |
1171 revs = _sortnodesnormal(filerevlog, filenodes, |
1171 self._reorder) |
1172 self._reorder) |
1172 |
1173 |
1173 progress.update(i + 1, item=fname) |
1174 progress.update(i + 1, item=fname) |
1174 |
1175 |
1175 it = deltagroup( |
1176 deltas = deltagroup( |
1176 self._repo, revs, filerevlog, False, lookupfilelog, |
1177 self._repo, revs, filerevlog, False, lookupfilelog, |
1177 self._deltaparentfn, self._builddeltaheader, |
1178 self._deltaparentfn, |
1178 ellipses=self._ellipses, |
1179 ellipses=self._ellipses, |
1179 clrevtolocalrev=clrevtolocalrev, |
1180 clrevtolocalrev=clrevtolocalrev, |
1180 fullclnodes=self._fullclnodes, |
1181 fullclnodes=self._fullclnodes, |
1181 precomputedellipsis=self._precomputedellipsis) |
1182 precomputedellipsis=self._precomputedellipsis) |
1182 |
1183 |
1183 yield fname, it |
1184 yield fname, deltas |
1184 |
1185 |
1185 progress.complete() |
1186 progress.complete() |
1186 |
1187 |
1187 def _deltaparentprev(store, rev, p1, p2, prev): |
1188 def _deltaparentprev(store, rev, p1, p2, prev): |
1188 """Resolve a delta parent to the previous revision. |
1189 """Resolve a delta parent to the previous revision. |