comparison mercurial/changegroup.py @ 38898:67f37e8a5490

changegroup: pass end of manifests marker into constructor cg3 inserts a custom marker in the stream once all manifests have been transferred. This is currently abstracted out by overriding a method. Let's pass the end of manifests marker in as an argument to avoid the extra method. Differential Revision: https://phab.mercurial-scm.org/D4080
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 02 Aug 2018 18:04:51 -0700
parents bd64b8b8f0dd
children 7a154778fb46
comparison
equal deleted inserted replaced
38897:bd64b8b8f0dd 38898:67f37e8a5490
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 bundlecaps=None): 525 bundlecaps=None):
525 """Given a source repo, construct a bundler. 526 """Given a source repo, construct a bundler.
526 527
527 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
528 changegroup. Used to facilitate sparse changegroups. 529 changegroup. Used to facilitate sparse changegroups.
529 530
530 builddeltaheader is a callable that constructs the header for a group 531 builddeltaheader is a callable that constructs the header for a group
531 delta. 532 delta.
533
534 manifestsend is a chunk to send after manifests have been fully emitted.
532 535
533 bundlecaps is optional and can be used to specify the set of 536 bundlecaps is optional and can be used to specify the set of
534 capabilities which can be used to build the bundle. While bundlecaps is 537 capabilities which can be used to build the bundle. While bundlecaps is
535 unused in core Mercurial, extensions rely on this feature to communicate 538 unused in core Mercurial, extensions rely on this feature to communicate
536 capabilities to customize the changegroup packer. 539 capabilities to customize the changegroup packer.
538 assert filematcher 541 assert filematcher
539 self._filematcher = filematcher 542 self._filematcher = filematcher
540 543
541 self.version = version 544 self.version = version
542 self._builddeltaheader = builddeltaheader 545 self._builddeltaheader = builddeltaheader
546 self._manifestsend = manifestsend
543 547
544 # Set of capabilities we can use to build the bundle. 548 # Set of capabilities we can use to build the bundle.
545 if bundlecaps is None: 549 if bundlecaps is None:
546 bundlecaps = set() 550 bundlecaps = set()
547 self._bundlecaps = bundlecaps 551 self._bundlecaps = bundlecaps
658 """Pack flat manifests into a changegroup stream.""" 662 """Pack flat manifests into a changegroup stream."""
659 assert not dir 663 assert not dir
660 for chunk in self.group(mfnodes, self._repo.manifestlog._revlog, 664 for chunk in self.group(mfnodes, self._repo.manifestlog._revlog,
661 lookuplinknode, units=_('manifests')): 665 lookuplinknode, units=_('manifests')):
662 yield chunk 666 yield chunk
663
664 def _manifestsdone(self):
665 return ''
666 667
667 def generate(self, commonrevs, clnodes, fastpathlinkrev, source): 668 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
668 '''yield a sequence of changegroup chunks (strings)''' 669 '''yield a sequence of changegroup chunks (strings)'''
669 repo = self._repo 670 repo = self._repo
670 cl = repo.changelog 671 cl = repo.changelog
852 for x in self._packmanifests(dir, prunednodes, 853 for x in self._packmanifests(dir, prunednodes,
853 makelookupmflinknode(dir, nodes)): 854 makelookupmflinknode(dir, nodes)):
854 size += len(x) 855 size += len(x)
855 yield x 856 yield x
856 self._verbosenote(_('%8.i (manifests)\n') % size) 857 self._verbosenote(_('%8.i (manifests)\n') % size)
857 yield self._manifestsdone() 858 yield self._manifestsend
858 859
859 # The 'source' parameter is useful for extensions 860 # The 'source' parameter is useful for extensions
860 def generatefiles(self, changedfiles, linknodes, commonrevs, source): 861 def generatefiles(self, changedfiles, linknodes, commonrevs, source):
861 changedfiles = list(filter(self._filematcher, changedfiles)) 862 changedfiles = list(filter(self._filematcher, changedfiles))
862 863
1097 deltachunks=(diffheader, data), 1098 deltachunks=(diffheader, data),
1098 ) 1099 )
1099 1100
1100 class cg2packer(cg1packer): 1101 class cg2packer(cg1packer):
1101 def __init__(self, repo, filematcher, version, builddeltaheader, 1102 def __init__(self, repo, filematcher, version, builddeltaheader,
1102 bundlecaps=None): 1103 manifestsend, bundlecaps=None):
1103 super(cg2packer, self).__init__(repo, filematcher, version, 1104 super(cg2packer, self).__init__(repo, filematcher, version,
1104 builddeltaheader, 1105 builddeltaheader, manifestsend,
1105 bundlecaps=bundlecaps) 1106 bundlecaps=bundlecaps)
1106 1107
1107 if self._reorder is None: 1108 if self._reorder is None:
1108 # Since generaldelta is directly supported by cg2, reordering 1109 # Since generaldelta is directly supported by cg2, reordering
1109 # generally doesn't help, so we disable it by default (treating 1110 # generally doesn't help, so we disable it by default (treating
1157 dirlog = self._repo.manifestlog._revlog.dirlog(dir) 1158 dirlog = self._repo.manifestlog._revlog.dirlog(dir)
1158 for chunk in self.group(mfnodes, dirlog, lookuplinknode, 1159 for chunk in self.group(mfnodes, dirlog, lookuplinknode,
1159 units=_('manifests')): 1160 units=_('manifests')):
1160 yield chunk 1161 yield chunk
1161 1162
1162 def _manifestsdone(self):
1163 return self.close()
1164
1165 def _makecg1packer(repo, filematcher, bundlecaps): 1163 def _makecg1packer(repo, filematcher, bundlecaps):
1166 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( 1164 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1167 d.node, d.p1node, d.p2node, d.linknode) 1165 d.node, d.p1node, d.p2node, d.linknode)
1168 1166
1169 return cg1packer(repo, filematcher, b'01', builddeltaheader, 1167 return cg1packer(repo, filematcher, b'01', builddeltaheader,
1168 manifestsend=b'',
1170 bundlecaps=bundlecaps) 1169 bundlecaps=bundlecaps)
1171 1170
1172 def _makecg2packer(repo, filematcher, bundlecaps): 1171 def _makecg2packer(repo, filematcher, bundlecaps):
1173 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( 1172 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1174 d.node, d.p1node, d.p2node, d.basenode, d.linknode) 1173 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1175 1174
1176 return cg2packer(repo, filematcher, b'02', builddeltaheader, 1175 return cg2packer(repo, filematcher, b'02', builddeltaheader,
1176 manifestsend=b'',
1177 bundlecaps=bundlecaps) 1177 bundlecaps=bundlecaps)
1178 1178
1179 def _makecg3packer(repo, filematcher, bundlecaps): 1179 def _makecg3packer(repo, filematcher, bundlecaps):
1180 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( 1180 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1181 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) 1181 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1182 1182
1183 return cg3packer(repo, filematcher, b'03', builddeltaheader, 1183 return cg3packer(repo, filematcher, b'03', builddeltaheader,
1184 manifestsend=closechunk(),
1184 bundlecaps=bundlecaps) 1185 bundlecaps=bundlecaps)
1185 1186
1186 _packermap = {'01': (_makecg1packer, cg1unpacker), 1187 _packermap = {'01': (_makecg1packer, cg1unpacker),
1187 # cg2 adds support for exchanging generaldelta 1188 # cg2 adds support for exchanging generaldelta
1188 '02': (_makecg2packer, cg2unpacker), 1189 '02': (_makecg2packer, cg2unpacker),