Mercurial > hg
comparison mercurial/changegroup.py @ 38899:7a154778fb46
changegroup: consolidate tree manifests sending into cg1packer
Previously, we overrode a method to control how manifests were
serialized. This method was redefined on cg3packer to send tree
manifests.
This commit moves the tree manifests sending variation to cg1packer
and teaches the cgpacker constructor to control which version to
use.
After these changes, cg3packer was empty. So it has been removed.
Differential Revision: https://phab.mercurial-scm.org/D4081
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 03 Aug 2018 09:44:30 -0700 |
parents | 67f37e8a5490 |
children | 6e999a2d8fe7 |
comparison
equal
deleted
inserted
replaced
38898:67f37e8a5490 | 38899:7a154778fb46 |
---|---|
519 # Iterable of chunks holding raw delta data. | 519 # Iterable of chunks holding raw delta data. |
520 deltachunks = attr.ib() | 520 deltachunks = attr.ib() |
521 | 521 |
522 class cg1packer(object): | 522 class cg1packer(object): |
523 def __init__(self, repo, filematcher, version, builddeltaheader, | 523 def __init__(self, repo, filematcher, version, builddeltaheader, |
524 manifestsend, | 524 manifestsend, sendtreemanifests, |
525 bundlecaps=None): | 525 bundlecaps=None): |
526 """Given a source repo, construct a bundler. | 526 """Given a source repo, construct a bundler. |
527 | 527 |
528 filematcher is a matcher that matches on files to include in the | 528 filematcher is a matcher that matches on files to include in the |
529 changegroup. Used to facilitate sparse changegroups. | 529 changegroup. Used to facilitate sparse changegroups. |
530 | 530 |
531 builddeltaheader is a callable that constructs the header for a group | 531 builddeltaheader is a callable that constructs the header for a group |
532 delta. | 532 delta. |
533 | 533 |
534 manifestsend is a chunk to send after manifests have been fully emitted. | 534 manifestsend is a chunk to send after manifests have been fully emitted. |
535 | |
536 sendtreemanifests indicates whether tree manifests should be emitted. | |
535 | 537 |
536 bundlecaps is optional and can be used to specify the set of | 538 bundlecaps is optional and can be used to specify the set of |
537 capabilities which can be used to build the bundle. While bundlecaps is | 539 capabilities which can be used to build the bundle. While bundlecaps is |
538 unused in core Mercurial, extensions rely on this feature to communicate | 540 unused in core Mercurial, extensions rely on this feature to communicate |
539 capabilities to customize the changegroup packer. | 541 capabilities to customize the changegroup packer. |
542 self._filematcher = filematcher | 544 self._filematcher = filematcher |
543 | 545 |
544 self.version = version | 546 self.version = version |
545 self._builddeltaheader = builddeltaheader | 547 self._builddeltaheader = builddeltaheader |
546 self._manifestsend = manifestsend | 548 self._manifestsend = manifestsend |
549 self._sendtreemanifests = sendtreemanifests | |
547 | 550 |
548 # Set of capabilities we can use to build the bundle. | 551 # Set of capabilities we can use to build the bundle. |
549 if bundlecaps is None: | 552 if bundlecaps is None: |
550 bundlecaps = set() | 553 bundlecaps = set() |
551 self._bundlecaps = bundlecaps | 554 self._bundlecaps = bundlecaps |
661 def _packmanifests(self, dir, mfnodes, lookuplinknode): | 664 def _packmanifests(self, dir, mfnodes, lookuplinknode): |
662 """Pack flat manifests into a changegroup stream.""" | 665 """Pack flat manifests into a changegroup stream.""" |
663 assert not dir | 666 assert not dir |
664 for chunk in self.group(mfnodes, self._repo.manifestlog._revlog, | 667 for chunk in self.group(mfnodes, self._repo.manifestlog._revlog, |
665 lookuplinknode, units=_('manifests')): | 668 lookuplinknode, units=_('manifests')): |
669 yield chunk | |
670 | |
671 def _packtreemanifests(self, dir, mfnodes, lookuplinknode): | |
672 """Version of _packmanifests that operates on directory manifests. | |
673 | |
674 Encodes the directory name in the output so multiple manifests | |
675 can be sent. | |
676 """ | |
677 assert self.version == b'03' | |
678 | |
679 if dir: | |
680 yield self.fileheader(dir) | |
681 | |
682 # TODO violates storage abstractions by assuming revlogs. | |
683 dirlog = self._repo.manifestlog._revlog.dirlog(dir) | |
684 for chunk in self.group(mfnodes, dirlog, lookuplinknode, | |
685 units=_('manifests')): | |
666 yield chunk | 686 yield chunk |
667 | 687 |
668 def generate(self, commonrevs, clnodes, fastpathlinkrev, source): | 688 def generate(self, commonrevs, clnodes, fastpathlinkrev, source): |
669 '''yield a sequence of changegroup chunks (strings)''' | 689 '''yield a sequence of changegroup chunks (strings)''' |
670 repo = self._repo | 690 repo = self._repo |
843 if clrevorder[clnode] < clrevorder[fclnode]: | 863 if clrevorder[clnode] < clrevorder[fclnode]: |
844 fclnodes[n] = clnode | 864 fclnodes[n] = clnode |
845 return clnode | 865 return clnode |
846 return lookupmflinknode | 866 return lookupmflinknode |
847 | 867 |
868 fn = (self._packtreemanifests if self._sendtreemanifests | |
869 else self._packmanifests) | |
848 size = 0 | 870 size = 0 |
849 while tmfnodes: | 871 while tmfnodes: |
850 dir, nodes = tmfnodes.popitem() | 872 dir, nodes = tmfnodes.popitem() |
851 prunednodes = self.prune(dirlog(dir), nodes, commonrevs) | 873 prunednodes = self.prune(dirlog(dir), nodes, commonrevs) |
852 if not dir or prunednodes: | 874 if not dir or prunednodes: |
853 for x in self._packmanifests(dir, prunednodes, | 875 for x in fn(dir, prunednodes, makelookupmflinknode(dir, nodes)): |
854 makelookupmflinknode(dir, nodes)): | |
855 size += len(x) | 876 size += len(x) |
856 yield x | 877 yield x |
857 self._verbosenote(_('%8.i (manifests)\n') % size) | 878 self._verbosenote(_('%8.i (manifests)\n') % size) |
858 yield self._manifestsend | 879 yield self._manifestsend |
859 | 880 |
1098 deltachunks=(diffheader, data), | 1119 deltachunks=(diffheader, data), |
1099 ) | 1120 ) |
1100 | 1121 |
1101 class cg2packer(cg1packer): | 1122 class cg2packer(cg1packer): |
1102 def __init__(self, repo, filematcher, version, builddeltaheader, | 1123 def __init__(self, repo, filematcher, version, builddeltaheader, |
1103 manifestsend, bundlecaps=None): | 1124 manifestsend, sendtreemanifests, bundlecaps=None): |
1104 super(cg2packer, self).__init__(repo, filematcher, version, | 1125 super(cg2packer, self).__init__(repo, filematcher, version, |
1105 builddeltaheader, manifestsend, | 1126 builddeltaheader, manifestsend, |
1127 sendtreemanifests, | |
1106 bundlecaps=bundlecaps) | 1128 bundlecaps=bundlecaps) |
1107 | 1129 |
1108 if self._reorder is None: | 1130 if self._reorder is None: |
1109 # Since generaldelta is directly supported by cg2, reordering | 1131 # Since generaldelta is directly supported by cg2, reordering |
1110 # generally doesn't help, so we disable it by default (treating | 1132 # generally doesn't help, so we disable it by default (treating |
1148 base = dp | 1170 base = dp |
1149 if base != nullrev and not store.candelta(base, rev): | 1171 if base != nullrev and not store.candelta(base, rev): |
1150 base = nullrev | 1172 base = nullrev |
1151 return base | 1173 return base |
1152 | 1174 |
1153 class cg3packer(cg2packer): | |
1154 def _packmanifests(self, dir, mfnodes, lookuplinknode): | |
1155 if dir: | |
1156 yield self.fileheader(dir) | |
1157 | |
1158 dirlog = self._repo.manifestlog._revlog.dirlog(dir) | |
1159 for chunk in self.group(mfnodes, dirlog, lookuplinknode, | |
1160 units=_('manifests')): | |
1161 yield chunk | |
1162 | |
1163 def _makecg1packer(repo, filematcher, bundlecaps): | 1175 def _makecg1packer(repo, filematcher, bundlecaps): |
1164 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( | 1176 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( |
1165 d.node, d.p1node, d.p2node, d.linknode) | 1177 d.node, d.p1node, d.p2node, d.linknode) |
1166 | 1178 |
1167 return cg1packer(repo, filematcher, b'01', builddeltaheader, | 1179 return cg1packer(repo, filematcher, b'01', builddeltaheader, |
1168 manifestsend=b'', | 1180 manifestsend=b'', sendtreemanifests=False, |
1169 bundlecaps=bundlecaps) | 1181 bundlecaps=bundlecaps) |
1170 | 1182 |
1171 def _makecg2packer(repo, filematcher, bundlecaps): | 1183 def _makecg2packer(repo, filematcher, bundlecaps): |
1172 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( | 1184 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( |
1173 d.node, d.p1node, d.p2node, d.basenode, d.linknode) | 1185 d.node, d.p1node, d.p2node, d.basenode, d.linknode) |
1174 | 1186 |
1175 return cg2packer(repo, filematcher, b'02', builddeltaheader, | 1187 return cg2packer(repo, filematcher, b'02', builddeltaheader, |
1176 manifestsend=b'', | 1188 manifestsend=b'', sendtreemanifests=False, |
1177 bundlecaps=bundlecaps) | 1189 bundlecaps=bundlecaps) |
1178 | 1190 |
1179 def _makecg3packer(repo, filematcher, bundlecaps): | 1191 def _makecg3packer(repo, filematcher, bundlecaps): |
1180 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( | 1192 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( |
1181 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) | 1193 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) |
1182 | 1194 |
1183 return cg3packer(repo, filematcher, b'03', builddeltaheader, | 1195 return cg2packer(repo, filematcher, b'03', builddeltaheader, |
1184 manifestsend=closechunk(), | 1196 manifestsend=closechunk(), sendtreemanifests=True, |
1185 bundlecaps=bundlecaps) | 1197 bundlecaps=bundlecaps) |
1186 | 1198 |
1187 _packermap = {'01': (_makecg1packer, cg1unpacker), | 1199 _packermap = {'01': (_makecg1packer, cg1unpacker), |
1188 # cg2 adds support for exchanging generaldelta | 1200 # cg2 adds support for exchanging generaldelta |
1189 '02': (_makecg2packer, cg2unpacker), | 1201 '02': (_makecg2packer, cg2unpacker), |