From patchwork Mon Aug 1 18:18:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [7, of, 9, changegroup-apis] changegroup: add and use getunbundler() to changegroupemitter From: Gregory Szorc X-Patchwork-Id: 16022 Message-Id: <707393be6c674cded252.1470075504@ubuntu-vm-main> To: mercurial-devel@mercurial-scm.org Date: Mon, 01 Aug 2016 11:18:24 -0700 # HG changeset patch # User Gregory Szorc # Date 1469909170 25200 # Sat Jul 30 13:06:10 2016 -0700 # Node ID 707393be6c674cded25255e4fa19d9b791b56f46 # Parent 39ff601b7117aecdd41ec1cc1a3539063c100e99 changegroup: add and use getunbundler() to changegroupemitter There were multiple uses of a similar pattern of obtaining changegroup data then converting it to an unbundler. We factor the common code into the changegroupemitter class. This API may change in patches ahead. The main goal of this patch is to pave the road for further removal of the low-level changegroup retrieval functions in changegroup.py. diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -909,40 +909,35 @@ def _changegroupinfo(repo, nodes, source repo.ui.status(_("%d changesets found\n") % len(nodes)) if repo.ui.debugflag: repo.ui.debug("list of changesets:\n") for node in nodes: repo.ui.debug("%s\n" % hex(node)) def getsubset(repo, outgoing, bundler, source, fastpath=False): emitter = changegroupemitter.fromoutgoing(repo, outgoing) - data = emitter.emitchangegroupdata(bundler.version, source, - bundler._bundlecaps, - fastpathlinkrev=fastpath) - - return getunbundler(bundler.version, util.chunkbuffer(data), None, - {'clcount': emitter.changesetcount}) + return emitter.getunbundler(bundler.version, source, + bundler._bundlecaps, + fastpathlinkrev=fastpath) def changegroupsubset(repo, roots, heads, source, version='01'): """Compute a changegroup consisting of all the nodes that are descendants of any of the roots and ancestors of any of the heads. Return a chunkbuffer object whose read() method will return successive changegroup chunks. It is fairly complex as determining which filenodes and which manifest nodes need to be included for the changeset to be complete is non-trivial. Another wrinkle is doing the reverse, figuring out which changeset in the changegroup a particular filenode or manifestnode belongs to. """ emitter = changegroupemitter.fromrootsandheads(repo, roots, heads) - data = emitter.emitchangegroupdata(version, source) - return getunbundler(version, util.chunkbuffer(data), None, - {'clcount': emitter.changesetcount}) + return emitter.getunbundler(version, source) def getlocalchangegroup(repo, source, outgoing, bundlecaps=None, version='01'): """Like getbundle, but taking a discovery.outgoing as an argument. This is only implemented for local repos and reuses potentially precomputed sets in outgoing.""" if not outgoing.missing: @@ -1124,8 +1119,23 @@ class changegroupemitter(object): bundler = getbundler(version, self._repo, bundlecaps=bundlecaps) self._repo.hook('preoutgoing', throw=True, source=source) _changegroupinfo(self._repo, self._nodes, source) return bundler.generate(self._commonrevs, self._nodes, fastpathlinkrev, source) + + def getunbundler(self, version, source, bundlecaps=None, + fastpathlinkrev=False): + """Obtain an unbundler for this changegroup. + + Returns an instance of ``cgNunpacker`` or None if the changegroup + is empty. + """ + data = self.emitchangegroupdata(version, source, bundlecaps=bundlecaps, + fastpathlinkrev=fastpathlinkrev) + if not data: + return None + + return getunbundler(version, util.chunkbuffer(data), None, + {'clcount': self.changesetcount})