diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -443,7 +443,7 @@ def _changegroupinfo(repo, nodes, source for node in nodes: repo.ui.debug("%s\n" % hex(node)) -def getsubset(repo, outgoing, bundler, source, fastpath=False): +def getsubsetraw(repo, outgoing, bundler, source, fastpath=False): repo = repo.unfiltered() commonrevs = outgoing.common csets = outgoing.missing @@ -457,7 +457,10 @@ def getsubset(repo, outgoing, bundler, s repo.hook('preoutgoing', throw=True, source=source) _changegroupinfo(repo, csets, source) - gengroup = bundler.generate(commonrevs, csets, fastpathlinkrev, source) + return bundler.generate(commonrevs, csets, fastpathlinkrev, source) + +def getsubset(repo, outgoing, bundler, source, fastpath=False): + gengroup = getsubsetraw(repo, outgoing, bundler, source, fastpath) return cg1unpacker(util.chunkbuffer(gengroup), 'UN') def changegroupsubset(repo, roots, heads, source): @@ -485,6 +488,16 @@ def changegroupsubset(repo, roots, heads bundler = cg1packer(repo) return getsubset(repo, outgoing, bundler, source) +def getlocalchangegroupraw(repo, source, outgoing, bundlecaps=None): + """Like getbundle, but taking a discovery.outgoing as an argument. + + This is only implemented for local repos and reuses potentially + precomputed sets in outgoing. Returns a raw changegroup generator.""" + if not outgoing.missing: + return None + bundler = cg1packer(repo, bundlecaps) + return getsubsetraw(repo, outgoing, bundler, source) + def getlocalchangegroup(repo, source, outgoing, bundlecaps=None): """Like getbundle, but taking a discovery.outgoing as an argument. @@ -514,6 +527,18 @@ def _computeoutgoing(repo, heads, common heads = cl.heads() return discovery.outgoing(cl, common, heads) +def getchangegroupraw(repo, source, heads=None, common=None, bundlecaps=None): + """Like changegroupsubset, but returns the set difference between the + ancestors of heads and the ancestors common. + + If heads is None, use the local heads. If common is None, use [nullid]. + + The nodes in common might not all be known locally due to the way the + current discovery protocol works. Returns a raw changegroup generator. + """ + outgoing = _computeoutgoing(repo, heads, common) + return getlocalchangegroupraw(repo, source, outgoing, bundlecaps=bundlecaps) + def getchangegroup(repo, source, heads=None, common=None, bundlecaps=None): """Like changegroupsubset, but returns the set difference between the ancestors of heads and the ancestors common. diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -445,8 +445,9 @@ def _pushb2ctx(pushop, bundler): pushop.outgoing) if not pushop.force: bundler.newpart('B2X:CHECK:HEADS', data=iter(pushop.remoteheads)) - cg = changegroup.getlocalchangegroup(pushop.repo, 'push', pushop.outgoing) - cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg.getchunks()) + cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push', + pushop.outgoing) + cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg) def handlereply(op): """extract addchangegroup returns from server reply""" cgreplies = op.records.getreplies(cgpart.id) @@ -1185,11 +1186,11 @@ def _getbundlechangegrouppart(bundler, r cg = None if kwargs.get('cg', True): # build changegroup bundle here. - cg = changegroup.getchangegroup(repo, source, heads=heads, - common=common, bundlecaps=bundlecaps) + cg = changegroup.getchangegroupraw(repo, source, heads=heads, + common=common, bundlecaps=bundlecaps) if cg: - bundler.newpart('b2x:changegroup', data=cg.getchunks()) + bundler.newpart('b2x:changegroup', data=cg) @getbundle2partsgenerator('listkeys') def _getbundlelistkeysparts(bundler, repo, source, bundlecaps=None,