Exemplo n.º 1
0
def _pullbundle2(pullop):
    """pull data using bundle2

    For now, the only supported data are changegroup."""
    remotecaps = bundle2.bundle2caps(pullop.remote)
    kwargs = {'bundlecaps': caps20to10(pullop.repo)}
    # pulling changegroup
    pullop.stepsdone.add('changegroup')

    kwargs['common'] = pullop.common
    kwargs['heads'] = pullop.heads or pullop.rheads
    kwargs['cg'] = pullop.fetch
    if 'b2x:listkeys' in remotecaps:
        kwargs['listkeys'] = ['phase', 'bookmarks']
    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"))
    if obsolete.isenabled(pullop.repo, obsolete.exchangeopt):
        remoteversions = bundle2.obsmarkersversion(remotecaps)
        if obsolete.commonversion(remoteversions) is not None:
            kwargs['obsmarkers'] = True
            pullop.stepsdone.add('obsmarkers')
    _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 error.BundleValueError, exc:
        raise util.Abort('missing support for %s' % exc)
Exemplo n.º 2
0
def _pushb2phases(pushop, bundler):
    """handle phase push through bundle2"""
    if 'phases' in pushop.stepsdone:
        return
    b2caps = bundle2.bundle2caps(pushop.remote)
    if not 'b2x:pushkey' in b2caps:
        return
    pushop.stepsdone.add('phases')
    part2node = []
    enc = pushkey.encode
    for newremotehead in pushop.outdatedphases:
        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))
    def handlereply(op):
        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)
    return handlereply
Exemplo n.º 3
0
def _pullbundle2(pullop):
    """pull data using bundle2

    For now, the only supported data are changegroup."""
    remotecaps = bundle2.bundle2caps(pullop.remote)
    kwargs = {'bundlecaps': caps20to10(pullop.repo)}
    # pulling changegroup
    pullop.todosteps.remove('changegroup')

    kwargs['common'] = pullop.common
    kwargs['heads'] = pullop.heads or pullop.rheads
    if 'b2x:listkeys' in remotecaps:
        kwargs['listkeys'] = ['phase']
    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 error.BundleValueError, exc:
        raise util.Abort('missing support for %s' % exc)
Exemplo n.º 4
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)
Exemplo n.º 5
0
def _pushb2phases(pushop, bundler):
    """handle phase push through bundle2"""
    if 'phases' in pushop.stepsdone:
        return
    b2caps = bundle2.bundle2caps(pushop.remote)
    if not 'b2x:pushkey' in b2caps:
        return
    pushop.stepsdone.add('phases')
    part2node = []
    enc = pushkey.encode
    for newremotehead in pushop.outdatedphases:
        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))

    def handlereply(op):
        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)

    return handlereply
Exemplo n.º 6
0
def _pushb2bookmarks(pushop, bundler):
    """handle phase push through bundle2"""
    if 'bookmarks' in pushop.stepsdone:
        return
    b2caps = bundle2.bundle2caps(pushop.remote)
    if 'b2x:pushkey' not in b2caps:
        return
    pushop.stepsdone.add('bookmarks')
    part2book = []
    enc = pushkey.encode
    for book, old, new in pushop.outbookmarks:
        part = bundler.newpart('b2x:pushkey')
        part.addparam('namespace', enc('bookmarks'))
        part.addparam('key', enc(book))
        part.addparam('old', enc(old))
        part.addparam('new', enc(new))
        action = 'update'
        if not old:
            action = 'export'
        elif not new:
            action = 'delete'
        part2book.append((part.id, book, action))


    def handlereply(op):
        ui = pushop.ui
        for partid, book, action in part2book:
            partrep = op.records.getreplies(partid)
            results = partrep['pushkey']
            assert len(results) <= 1
            if not results:
                pushop.ui.warn(_('server ignored bookmark %s update\n') % book)
            else:
                ret = int(results[0]['return'])
                if ret:
                    ui.status(bookmsgmap[action][0] % book)
                else:
                    ui.warn(bookmsgmap[action][1] % book)
                    if pushop.bkresult is not None:
                        pushop.bkresult = 1
    return handlereply
Exemplo n.º 7
0
def _pushb2bookmarks(pushop, bundler):
    """handle phase push through bundle2"""
    if 'bookmarks' in pushop.stepsdone:
        return
    b2caps = bundle2.bundle2caps(pushop.remote)
    if 'b2x:pushkey' not in b2caps:
        return
    pushop.stepsdone.add('bookmarks')
    part2book = []
    enc = pushkey.encode
    for book, old, new in pushop.outbookmarks:
        part = bundler.newpart('b2x:pushkey')
        part.addparam('namespace', enc('bookmarks'))
        part.addparam('key', enc(book))
        part.addparam('old', enc(old))
        part.addparam('new', enc(new))
        action = 'update'
        if not old:
            action = 'export'
        elif not new:
            action = 'delete'
        part2book.append((part.id, book, action))

    def handlereply(op):
        ui = pushop.ui
        for partid, book, action in part2book:
            partrep = op.records.getreplies(partid)
            results = partrep['pushkey']
            assert len(results) <= 1
            if not results:
                pushop.ui.warn(_('server ignored bookmark %s update\n') % book)
            else:
                ret = int(results[0]['return'])
                if ret:
                    ui.status(bookmsgmap[action][0] % book)
                else:
                    ui.warn(bookmsgmap[action][1] % book)
                    if pushop.bkresult is not None:
                        pushop.bkresult = 1

    return handlereply
Exemplo n.º 8
0
def _pushb2ctx(pushop, bundler):
    """handle changegroup push through bundle2

    addchangegroup result is stored in the ``pushop.cgresult`` attribute.
    """
    if 'changesets' in pushop.stepsdone:
        return
    pushop.stepsdone.add('changesets')
    # Send known heads to the server for race detection.
    if not _pushcheckoutgoing(pushop):
        return
    pushop.repo.prepushoutgoinghooks(pushop.repo,
                                     pushop.remote,
                                     pushop.outgoing)
    if not pushop.force:
        bundler.newpart('b2x:check:heads', data=iter(pushop.remoteheads))
    b2caps = bundle2.bundle2caps(pushop.remote)
    version = None
    cgversions = b2caps.get('b2x:changegroup')
    if not cgversions:  # 3.1 and 3.2 ship with an empty value
        cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push',
                                                pushop.outgoing)
    else:
        cgversions = [v for v in cgversions if v in changegroup.packermap]
        if not cgversions:
            raise ValueError(_('no common changegroup version'))
        version = max(cgversions)
        cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push',
                                                pushop.outgoing,
                                                version=version)
    cgpart = bundler.newpart('b2x:changegroup', data=cg)
    if version is not None:
        cgpart.addparam('version', version)
    def handlereply(op):
        """extract addchangegroup returns from server reply"""
        cgreplies = op.records.getreplies(cgpart.id)
        assert len(cgreplies['changegroup']) == 1
        pushop.cgresult = cgreplies['changegroup'][0]['return']
    return handlereply
Exemplo n.º 9
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)
Exemplo n.º 10
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: