diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py index 166392155d..b2bf710574 100644 --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -494,9 +494,18 @@ class headerlessfixup(object): class cg1packer(object): deltaheader = _CHANGEGROUPV1_DELTA_HEADER version = '01' - def __init__(self, repo): + def __init__(self, repo, bundlecaps=None): """Given a source repo, construct a bundler. + + bundlecaps is optional and can be used to specify the set of + capabilities which can be used to build the bundle. While bundlecaps is + unused in core Mercurial, extensions rely on this feature to communicate + capabilities to customize the changegroup packer. """ + # Set of capabilities we can use to build the bundle. + if bundlecaps is None: + bundlecaps = set() + self._bundlecaps = bundlecaps # experimental config: bundle.reorder reorder = repo.ui.config('bundle', 'reorder', 'auto') if reorder == 'auto': @@ -800,8 +809,8 @@ class cg2packer(cg1packer): version = '02' deltaheader = _CHANGEGROUPV2_DELTA_HEADER - def __init__(self, repo): - super(cg2packer, self).__init__(repo) + def __init__(self, repo, bundlecaps=None): + super(cg2packer, self).__init__(repo, bundlecaps) if self._reorder is None: # Since generaldelta is directly supported by cg2, reordering # generally doesn't help, so we disable it by default (treating @@ -895,9 +904,9 @@ def safeversion(repo): assert versions return min(versions) -def getbundler(version, repo): +def getbundler(version, repo, bundlecaps=None): assert version in supportedoutgoingversions(repo) - return _packermap[version][0](repo) + return _packermap[version][0](repo, bundlecaps) def getunbundler(version, fh, alg, extras=None): return _packermap[version][1](fh, alg, extras=extras) @@ -948,24 +957,26 @@ def changegroupsubset(repo, roots, heads, source, version='01'): bundler = getbundler(version, repo) return getsubset(repo, outgoing, bundler, source) -def getlocalchangegroupraw(repo, source, outgoing, version='01'): +def getlocalchangegroupraw(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. Returns a raw changegroup generator.""" if not outgoing.missing: return None - bundler = getbundler(version, repo) + bundler = getbundler(version, repo, bundlecaps) return getsubsetraw(repo, outgoing, bundler, source) -def getchangegroup(repo, source, outgoing, version='01'): +def getchangegroup(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: return None - bundler = getbundler(version, repo) + bundler = getbundler(version, repo, bundlecaps) return getsubset(repo, outgoing, bundler, source) def getlocalchangegroup(repo, *args, **kwargs): diff --git a/mercurial/exchange.py b/mercurial/exchange.py index a22bda4694..21f2c505f4 100644 --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -936,19 +936,22 @@ def _pushchangeset(pushop): pushop.repo.prepushoutgoinghooks(pushop) outgoing = pushop.outgoing unbundle = pushop.remote.capable('unbundle') + # TODO: get bundlecaps from remote + bundlecaps = None # create a changegroup from local if pushop.revs is None and not (outgoing.excluded or pushop.repo.changelog.filteredrevs): # push everything, # use the fast path, no race possible on push - bundler = changegroup.cg1packer(pushop.repo) + bundler = changegroup.cg1packer(pushop.repo, bundlecaps) cg = changegroup.getsubset(pushop.repo, outgoing, bundler, 'push', fastpath=True) else: - cg = changegroup.getchangegroup(pushop.repo, 'push', outgoing) + cg = changegroup.getchangegroup(pushop.repo, 'push', outgoing, + bundlecaps=bundlecaps) # apply changegroup to remote if unbundle: @@ -1575,7 +1578,7 @@ def getbundlechunks(repo, source, heads=None, common=None, bundlecaps=None, raise ValueError(_('unsupported getbundle arguments: %s') % ', '.join(sorted(kwargs.keys()))) outgoing = _computeoutgoing(repo, heads, common) - bundler = changegroup.getbundler('01', repo) + bundler = changegroup.getbundler('01', repo, bundlecaps) return changegroup.getsubsetraw(repo, outgoing, bundler, source) # bundle20 case @@ -1613,6 +1616,7 @@ def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None, version = max(cgversions) outgoing = _computeoutgoing(repo, heads, common) cg = changegroup.getlocalchangegroupraw(repo, source, outgoing, + bundlecaps=bundlecaps, version=version) if cg: diff --git a/tests/test-bundle2-format.t b/tests/test-bundle2-format.t index 5351a1b911..558976f493 100644 --- a/tests/test-bundle2-format.t +++ b/tests/test-bundle2-format.t @@ -113,7 +113,7 @@ Create an extension to test bundle2 API > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)] > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)] > outgoing = discovery.outgoing(repo, headcommon, headmissing) - > cg = changegroup.getchangegroup(repo, 'test:bundle2', outgoing) + > cg = changegroup.getchangegroup(repo, 'test:bundle2', outgoing, None) > bundler.newpart('changegroup', data=cg.getchunks(), > mandatory=False) > diff --git a/tests/test-bundle2-multiple-changegroups.t b/tests/test-bundle2-multiple-changegroups.t index 782441777e..d8153aabf5 100644 --- a/tests/test-bundle2-multiple-changegroups.t +++ b/tests/test-bundle2-multiple-changegroups.t @@ -13,11 +13,13 @@ Create an extension to test bundle2 with multiple changegroups > # in 'heads' as intermediate heads for the first changegroup. > intermediates = [repo[r].p1().node() for r in heads] > outgoing = discovery.outgoing(repo, common, intermediates) - > cg = changegroup.getchangegroup(repo, source, outgoing) + > cg = changegroup.getchangegroup(repo, source, outgoing, + > bundlecaps=bundlecaps) > bundler.newpart('output', data='changegroup1') > bundler.newpart('changegroup', data=cg.getchunks()) > outgoing = discovery.outgoing(repo, common + intermediates, heads) - > cg = changegroup.getchangegroup(repo, source, outgoing) + > cg = changegroup.getchangegroup(repo, source, outgoing, + > bundlecaps=bundlecaps) > bundler.newpart('output', data='changegroup2') > bundler.newpart('changegroup', data=cg.getchunks()) >