Exemple #1
0
def _capabilities(repo, proto):
    """return a list of capabilities for a repo

    This function exists to allow extensions to easily wrap capabilities
    computation

    - returns a lists: easy to alter
    - change done here will be propagated to both `capabilities` and `hello`
      command without any other action needed.
    """
    # copy to prevent modification of the global list
    caps = list(wireprotocaps)
    if _allowstream(repo.ui):
        if repo.ui.configbool('server', 'preferuncompressed', False):
            caps.append('stream-preferred')
        requiredformats = repo.requirements & repo.supportedformats
        # if our local revlogs are just revlogv1, add 'stream' cap
        if not requiredformats - set(('revlogv1',)):
            caps.append('stream')
        # otherwise, add 'streamreqs' detailing our local revlog format
        else:
            caps.append('streamreqs=%s' % ','.join(requiredformats))
    if repo.ui.configbool('experimental', 'bundle2-exp', False):
        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
        caps.append('bundle2-exp=' + urllib.quote(capsblob))
    caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
    caps.append('httpheader=1024')
    return caps
def _pullbundle2(pullop):
    """pull data using bundle2

    For now, the only supported data are changegroup."""
    kwargs = {'bundlecaps': set(['HG2X'])}
    capsblob = bundle2.encodecaps(pullop.repo.bundle2caps)
    kwargs['bundlecaps'].add('bundle2=' + urllib.quote(capsblob))
    # pulling changegroup
    pullop.todosteps.remove('changegroup')

    kwargs['common'] = pullop.common
    kwargs['heads'] = pullop.heads or pullop.rheads
    if not pullop.fetch:
        pullop.repo.ui.status(_("no changes found\n"))
        pullop.cgresult = 0
    else:
        if pullop.heads is None and list(pullop.common) == [nullid]:
            pullop.repo.ui.status(_("requesting all changes\n"))
    _pullbundle2extraprepare(pullop, kwargs)
    if kwargs.keys() == ['format']:
        return  # nothing to pull
    bundle = pullop.remote.getbundle('pull', **kwargs)
    try:
        op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
    except bundle2.UnknownPartError, exc:
        raise util.Abort('missing support for %s' % exc)
Exemple #3
0
def _pushbundle2(pushop):
    """push data to the remote using bundle2

    The only currently supported type of data is changegroup but this will
    evolve in the future."""
    bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote))
    pushback = (pushop.trmanager
                and pushop.ui.configbool('experimental', 'bundle2.pushback'))

    # create reply capability
    capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo,
                                                      allowpushback=pushback))
    bundler.newpart('b2x:replycaps', data=capsblob)
    replyhandlers = []
    for partgenname in b2partsgenorder:
        partgen = b2partsgenmapping[partgenname]
        ret = partgen(pushop, bundler)
        if callable(ret):
            replyhandlers.append(ret)
    # do not push if nothing to push
    if bundler.nbparts <= 1:
        return
    stream = util.chunkbuffer(bundler.getchunks())
    try:
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
    except error.BundleValueError, exc:
        raise util.Abort('missing support for %s' % exc)
def _pushbundle2(pushop):
    """push data to the remote using bundle2

    The only currently supported type of data is changegroup but this will
    evolve in the future."""
    # Send known head to the server for race detection.
    capsblob = urllib.unquote(pushop.remote.capable('bundle2-exp'))
    caps = bundle2.decodecaps(capsblob)
    bundler = bundle2.bundle20(pushop.ui, caps)
    # create reply capability
    capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
    bundler.addpart(bundle2.bundlepart('b2x:replycaps', data=capsblob))
    if not pushop.force:
        part = bundle2.bundlepart('B2X:CHECK:HEADS',
                                  data=iter(pushop.remoteheads))
        bundler.addpart(part)
    extrainfo = _pushbundle2extraparts(pushop, bundler)
    # add the changegroup bundle
    cg = changegroup.getlocalbundle(pushop.repo, 'push', pushop.outgoing)
    cgpart = bundle2.bundlepart('B2X:CHANGEGROUP', data=cg.getchunks())
    bundler.addpart(cgpart)
    stream = util.chunkbuffer(bundler.getchunks())
    try:
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
    except bundle2.UnknownPartError, exc:
        raise util.Abort('missing support for %s' % exc)
Exemple #5
0
def _capabilities(repo, proto):
    """return a list of capabilities for a repo

    This function exists to allow extensions to easily wrap capabilities
    computation

    - returns a lists: easy to alter
    - change done here will be propagated to both `capabilities` and `hello`
      command without any other action needed.
    """
    # copy to prevent modification of the global list
    caps = list(wireprotocaps)
    if _allowstream(repo.ui):
        if repo.ui.configbool("server", "preferuncompressed", False):
            caps.append("stream-preferred")
        requiredformats = repo.requirements & repo.supportedformats
        # if our local revlogs are just revlogv1, add 'stream' cap
        if not requiredformats - set(("revlogv1",)):
            caps.append("stream")
        # otherwise, add 'streamreqs' detailing our local revlog format
        else:
            caps.append("streamreqs=%s" % ",".join(requiredformats))
    if repo.ui.configbool("experimental", "bundle2-advertise", True):
        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
        caps.append("bundle2=" + urllib.quote(capsblob))
    caps.append("unbundle=%s" % ",".join(changegroupmod.bundlepriority))
    caps.append("httpheader=%d" % repo.ui.configint("server", "maxhttpheaderlen", 1024))
    return caps
def _pullbundle2(pullop):
    """pull data using bundle2

    For now, the only supported data are changegroup."""
    kwargs = {'bundlecaps': set(['HG2X'])}
    capsblob = bundle2.encodecaps(pullop.repo.bundle2caps)
    kwargs['bundlecaps'].add('bundle2=' + urllib.quote(capsblob))
    # pulling changegroup
    pullop.todosteps.remove('changegroup')

    kwargs['common'] = pullop.common
    kwargs['heads'] = pullop.heads or pullop.rheads
    if not pullop.fetch:
        pullop.repo.ui.status(_("no changes found\n"))
        pullop.cgresult = 0
    else:
        if pullop.heads is None and list(pullop.common) == [nullid]:
            pullop.repo.ui.status(_("requesting all changes\n"))
    _pullbundle2extraprepare(pullop, kwargs)
    if kwargs.keys() == ['format']:
        return # nothing to pull
    bundle = pullop.remote.getbundle('pull', **kwargs)
    try:
        op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
    except bundle2.UnknownPartError, exc:
        raise util.Abort('missing support for %s' % exc)
def _pushbundle2(pushop):
    """push data to the remote using bundle2

    The only currently supported type of data is changegroup but this will
    evolve in the future."""
    # Send known head to the server for race detection.
    capsblob = urllib.unquote(pushop.remote.capable('bundle2-exp'))
    caps = bundle2.decodecaps(capsblob)
    bundler = bundle2.bundle20(pushop.ui, caps)
    # create reply capability
    capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
    bundler.addpart(bundle2.bundlepart('b2x:replycaps', data=capsblob))
    if not pushop.force:
        part = bundle2.bundlepart('B2X:CHECK:HEADS',
                                  data=iter(pushop.remoteheads))
        bundler.addpart(part)
    extrainfo = _pushbundle2extraparts(pushop, bundler)
    # add the changegroup bundle
    cg = changegroup.getlocalbundle(pushop.repo, 'push', pushop.outgoing)
    cgpart = bundle2.bundlepart('B2X:CHANGEGROUP', data=cg.getchunks())
    bundler.addpart(cgpart)
    stream = util.chunkbuffer(bundler.getchunks())
    try:
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
    except bundle2.UnknownPartError, exc:
        raise util.Abort('missing support for %s' % exc)
Exemple #8
0
def _pushbundle2(pushop):
    """push data to the remote using bundle2

    The only currently supported type of data is changegroup but this will
    evolve in the future."""
    bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote))
    # create reply capability
    capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
    bundler.newpart('b2x:replycaps', data=capsblob)
    replyhandlers = []
    for partgen in bundle2partsgenerators:
        ret = partgen(pushop, bundler)
        if callable(ret):
            replyhandlers.append(ret)
    # do not push if nothing to push
    if bundler.nbparts <= 1:
        return
    stream = util.chunkbuffer(bundler.getchunks())
    try:
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
    except error.BundleValueError, exc:
        raise util.Abort('missing support for %s' % exc)
def caps20to10(repo):
    """return a set with appropriate options to use bundle20 during getbundle"""
    caps = set(['HG2Y'])
    capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
    caps.add('bundle2=' + urllib.quote(capsblob))
    return caps
Exemple #10
0
def caps20to10(repo):
    """return a set with appropriate options to use bundle20 during getbundle"""
    caps = set(['HG2X'])
    capsblob = bundle2.encodecaps(repo.bundle2caps)
    caps.add('bundle2=' + urllib.quote(capsblob))
    return caps
Exemple #11
0
def _pushsyncphase(pushop):
    """synchronise phase information locally and remotely"""
    unfi = pushop.repo.unfiltered()
    cheads = pushop.commonheads
    # even when we don't push, exchanging phase data is useful
    remotephases = pushop.remote.listkeys('phases')
    if (pushop.ui.configbool('ui', '_usedassubrepo', False)
        and remotephases    # server supports phases
        and pushop.ret is None # nothing was pushed
        and remotephases.get('publishing', False)):
        # When:
        # - this is a subrepo push
        # - and remote support phase
        # - and no changeset was pushed
        # - and remote is publishing
        # We may be in issue 3871 case!
        # We drop the possible phase synchronisation done by
        # courtesy to publish changesets possibly locally draft
        # on the remote.
        remotephases = {'publishing': 'True'}
    if not remotephases: # old server or public only reply from non-publishing
        _localphasemove(pushop, cheads)
        # don't push any phase data as there is nothing to push
    else:
        ana = phases.analyzeremotephases(pushop.repo, cheads,
                                         remotephases)
        pheads, droots = ana
        ### Apply remote phase on local
        if remotephases.get('publishing', False):
            _localphasemove(pushop, cheads)
        else: # publish = False
            _localphasemove(pushop, pheads)
            _localphasemove(pushop, cheads, phases.draft)
        ### Apply local phase on remote

        # Get the list of all revs draft on remote by public here.
        # XXX Beware that revset break if droots is not strictly
        # XXX root we may want to ensure it is but it is costly
        outdated = unfi.set('heads((%ln::%ln) and public())',
                            droots, cheads)

        b2caps = bundle2.bundle2caps(pushop.remote)
        if 'b2x:pushkey' in b2caps:
            # server supports bundle2, let's do a batched push through it
            #
            # This will eventually be unified with the changesets bundle2 push
            bundler = bundle2.bundle20(pushop.ui, b2caps)
            capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
            bundler.newpart('b2x:replycaps', data=capsblob)
            part2node = []
            enc = pushkey.encode
            for newremotehead in outdated:
                part = bundler.newpart('b2x:pushkey')
                part.addparam('namespace', enc('phases'))
                part.addparam('key', enc(newremotehead.hex()))
                part.addparam('old', enc(str(phases.draft)))
                part.addparam('new', enc(str(phases.public)))
                part2node.append((part.id, newremotehead))
            stream = util.chunkbuffer(bundler.getchunks())
            try:
                reply = pushop.remote.unbundle(stream, ['force'], 'push')
                op = bundle2.processbundle(pushop.repo, reply)
            except error.BundleValueError, exc:
                raise util.Abort('missing support for %s' % exc)
            for partid, node in part2node:
                partrep = op.records.getreplies(partid)
                results = partrep['pushkey']
                assert len(results) <= 1
                msg = None
                if not results:
                    msg = _('server ignored update of %s to public!\n') % node
                elif not int(results[0]['return']):
                    msg = _('updating %s to public failed!\n') % node
                if msg is not None:
                    pushop.ui.warn(msg)

        else: