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.
| hg-reviewers |
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.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/changegroup.py (19 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg |
| linknode = attr.ib() | linknode = attr.ib() | ||||
| # 2 bytes of flags to apply to revision data. | # 2 bytes of flags to apply to revision data. | ||||
| flags = attr.ib() | flags = attr.ib() | ||||
| # Iterable of chunks holding raw delta data. | # Iterable of chunks holding raw delta data. | ||||
| deltachunks = attr.ib() | deltachunks = attr.ib() | ||||
| class cg1packer(object): | class cg1packer(object): | ||||
| def __init__(self, repo, filematcher, version, builddeltaheader, | def __init__(self, repo, filematcher, version, builddeltaheader, | ||||
| manifestsend, | |||||
| bundlecaps=None): | bundlecaps=None): | ||||
| """Given a source repo, construct a bundler. | """Given a source repo, construct a bundler. | ||||
| filematcher is a matcher that matches on files to include in the | filematcher is a matcher that matches on files to include in the | ||||
| changegroup. Used to facilitate sparse changegroups. | changegroup. Used to facilitate sparse changegroups. | ||||
| builddeltaheader is a callable that constructs the header for a group | builddeltaheader is a callable that constructs the header for a group | ||||
| delta. | delta. | ||||
| manifestsend is a chunk to send after manifests have been fully emitted. | |||||
| bundlecaps is optional and can be used to specify the set of | bundlecaps is optional and can be used to specify the set of | ||||
| capabilities which can be used to build the bundle. While bundlecaps is | capabilities which can be used to build the bundle. While bundlecaps is | ||||
| unused in core Mercurial, extensions rely on this feature to communicate | unused in core Mercurial, extensions rely on this feature to communicate | ||||
| capabilities to customize the changegroup packer. | capabilities to customize the changegroup packer. | ||||
| """ | """ | ||||
| assert filematcher | assert filematcher | ||||
| self._filematcher = filematcher | self._filematcher = filematcher | ||||
| self.version = version | self.version = version | ||||
| self._builddeltaheader = builddeltaheader | self._builddeltaheader = builddeltaheader | ||||
| self._manifestsend = manifestsend | |||||
| # Set of capabilities we can use to build the bundle. | # Set of capabilities we can use to build the bundle. | ||||
| if bundlecaps is None: | if bundlecaps is None: | ||||
| bundlecaps = set() | bundlecaps = set() | ||||
| self._bundlecaps = bundlecaps | self._bundlecaps = bundlecaps | ||||
| # experimental config: bundle.reorder | # experimental config: bundle.reorder | ||||
| reorder = repo.ui.config('bundle', 'reorder') | reorder = repo.ui.config('bundle', 'reorder') | ||||
| if reorder == 'auto': | if reorder == 'auto': | ||||
| def _packmanifests(self, dir, mfnodes, lookuplinknode): | def _packmanifests(self, dir, mfnodes, lookuplinknode): | ||||
| """Pack flat manifests into a changegroup stream.""" | """Pack flat manifests into a changegroup stream.""" | ||||
| assert not dir | assert not dir | ||||
| for chunk in self.group(mfnodes, self._repo.manifestlog._revlog, | for chunk in self.group(mfnodes, self._repo.manifestlog._revlog, | ||||
| lookuplinknode, units=_('manifests')): | lookuplinknode, units=_('manifests')): | ||||
| yield chunk | yield chunk | ||||
| def _manifestsdone(self): | |||||
| return '' | |||||
| def generate(self, commonrevs, clnodes, fastpathlinkrev, source): | def generate(self, commonrevs, clnodes, fastpathlinkrev, source): | ||||
| '''yield a sequence of changegroup chunks (strings)''' | '''yield a sequence of changegroup chunks (strings)''' | ||||
| repo = self._repo | repo = self._repo | ||||
| cl = repo.changelog | cl = repo.changelog | ||||
| clrevorder = {} | clrevorder = {} | ||||
| mfs = {} # needed manifests | mfs = {} # needed manifests | ||||
| fnodes = {} # needed file nodes | fnodes = {} # needed file nodes | ||||
| dir, nodes = tmfnodes.popitem() | dir, nodes = tmfnodes.popitem() | ||||
| prunednodes = self.prune(dirlog(dir), nodes, commonrevs) | prunednodes = self.prune(dirlog(dir), nodes, commonrevs) | ||||
| if not dir or prunednodes: | if not dir or prunednodes: | ||||
| for x in self._packmanifests(dir, prunednodes, | for x in self._packmanifests(dir, prunednodes, | ||||
| makelookupmflinknode(dir, nodes)): | makelookupmflinknode(dir, nodes)): | ||||
| size += len(x) | size += len(x) | ||||
| yield x | yield x | ||||
| self._verbosenote(_('%8.i (manifests)\n') % size) | self._verbosenote(_('%8.i (manifests)\n') % size) | ||||
| yield self._manifestsdone() | yield self._manifestsend | ||||
| # The 'source' parameter is useful for extensions | # The 'source' parameter is useful for extensions | ||||
| def generatefiles(self, changedfiles, linknodes, commonrevs, source): | def generatefiles(self, changedfiles, linknodes, commonrevs, source): | ||||
| changedfiles = list(filter(self._filematcher, changedfiles)) | changedfiles = list(filter(self._filematcher, changedfiles)) | ||||
| if getattr(self, 'is_shallow', False): | if getattr(self, 'is_shallow', False): | ||||
| # See comment in generate() for why this sadness is a thing. | # See comment in generate() for why this sadness is a thing. | ||||
| mfdicts = self._mfdicts | mfdicts = self._mfdicts | ||||
| basenode=nullid, | basenode=nullid, | ||||
| linknode=linknode, | linknode=linknode, | ||||
| flags=flags, | flags=flags, | ||||
| deltachunks=(diffheader, data), | deltachunks=(diffheader, data), | ||||
| ) | ) | ||||
| class cg2packer(cg1packer): | class cg2packer(cg1packer): | ||||
| def __init__(self, repo, filematcher, version, builddeltaheader, | def __init__(self, repo, filematcher, version, builddeltaheader, | ||||
| bundlecaps=None): | manifestsend, bundlecaps=None): | ||||
| super(cg2packer, self).__init__(repo, filematcher, version, | super(cg2packer, self).__init__(repo, filematcher, version, | ||||
| builddeltaheader, | builddeltaheader, manifestsend, | ||||
| bundlecaps=bundlecaps) | bundlecaps=bundlecaps) | ||||
| if self._reorder is None: | if self._reorder is None: | ||||
| # Since generaldelta is directly supported by cg2, reordering | # Since generaldelta is directly supported by cg2, reordering | ||||
| # generally doesn't help, so we disable it by default (treating | # generally doesn't help, so we disable it by default (treating | ||||
| # bundle.reorder=auto just like bundle.reorder=False). | # bundle.reorder=auto just like bundle.reorder=False). | ||||
| self._reorder = False | self._reorder = False | ||||
| if dir: | if dir: | ||||
| yield self.fileheader(dir) | yield self.fileheader(dir) | ||||
| dirlog = self._repo.manifestlog._revlog.dirlog(dir) | dirlog = self._repo.manifestlog._revlog.dirlog(dir) | ||||
| for chunk in self.group(mfnodes, dirlog, lookuplinknode, | for chunk in self.group(mfnodes, dirlog, lookuplinknode, | ||||
| units=_('manifests')): | units=_('manifests')): | ||||
| yield chunk | yield chunk | ||||
| def _manifestsdone(self): | |||||
| return self.close() | |||||
| def _makecg1packer(repo, filematcher, bundlecaps): | def _makecg1packer(repo, filematcher, bundlecaps): | ||||
| builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( | builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( | ||||
| d.node, d.p1node, d.p2node, d.linknode) | d.node, d.p1node, d.p2node, d.linknode) | ||||
| return cg1packer(repo, filematcher, b'01', builddeltaheader, | return cg1packer(repo, filematcher, b'01', builddeltaheader, | ||||
| manifestsend=b'', | |||||
| bundlecaps=bundlecaps) | bundlecaps=bundlecaps) | ||||
| def _makecg2packer(repo, filematcher, bundlecaps): | def _makecg2packer(repo, filematcher, bundlecaps): | ||||
| builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( | builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( | ||||
| d.node, d.p1node, d.p2node, d.basenode, d.linknode) | d.node, d.p1node, d.p2node, d.basenode, d.linknode) | ||||
| return cg2packer(repo, filematcher, b'02', builddeltaheader, | return cg2packer(repo, filematcher, b'02', builddeltaheader, | ||||
| manifestsend=b'', | |||||
| bundlecaps=bundlecaps) | bundlecaps=bundlecaps) | ||||
| def _makecg3packer(repo, filematcher, bundlecaps): | def _makecg3packer(repo, filematcher, bundlecaps): | ||||
| builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( | builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( | ||||
| d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) | d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) | ||||
| return cg3packer(repo, filematcher, b'03', builddeltaheader, | return cg3packer(repo, filematcher, b'03', builddeltaheader, | ||||
| manifestsend=closechunk(), | |||||
| bundlecaps=bundlecaps) | bundlecaps=bundlecaps) | ||||
| _packermap = {'01': (_makecg1packer, cg1unpacker), | _packermap = {'01': (_makecg1packer, cg1unpacker), | ||||
| # cg2 adds support for exchanging generaldelta | # cg2 adds support for exchanging generaldelta | ||||
| '02': (_makecg2packer, cg2unpacker), | '02': (_makecg2packer, cg2unpacker), | ||||
| # cg3 adds support for exchanging revlog flags and treemanifests | # cg3 adds support for exchanging revlog flags and treemanifests | ||||
| '03': (_makecg3packer, cg3unpacker), | '03': (_makecg3packer, cg3unpacker), | ||||
| } | } | ||||