mercurial/exchange.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Fri, 17 Oct 2014 22:23:06 -0700
changeset 23361 936b0ff34346
parent 23282 6c1351352b6c
child 23382 a81c76106d90
permissions -rw-r--r--
phases: read pending data when appropriate If we are called by a hook and pending data exists, read those.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
     1
# exchange.py - utility to exchange data between repos.
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     2
#
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     4
#
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     7
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     8
from i18n import _
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
     9
from node import hex, nullid
21141
d8dd19e09ed4 bundle2: advertise bundle2 caps in server capabilities
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21130
diff changeset
    10
import errno, urllib
21184
28d76afa1568 bundle2: fix raising errors during heads checking
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21182
diff changeset
    11
import util, scmutil, changegroup, base85, error
22622
ce6b9edee725 exchange: import bookmarks as bookmod
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22616
diff changeset
    12
import discovery, phases, obsolete, bookmarks as bookmod, bundle2, pushkey
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    13
21064
4d9d490d7bbe bundle2: add a ui argument to readbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21063
diff changeset
    14
def readbundle(ui, fh, fname, vfs=None):
21065
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    15
    header = changegroup.readexactly(fh, 4)
21063
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    16
21065
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    17
    alg = None
21063
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    18
    if not fname:
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    19
        fname = "stream"
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    20
        if not header.startswith('HG') and header.startswith('\0'):
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    21
            fh = changegroup.headerlessfixup(fh, header)
21065
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    22
            header = "HG10"
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    23
            alg = 'UN'
21063
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    24
    elif vfs:
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    25
        fname = vfs.join(fname)
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    26
21065
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    27
    magic, version = header[0:2], header[2:4]
21063
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    28
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    29
    if magic != 'HG':
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    30
        raise util.Abort(_('%s: not a Mercurial bundle') % fname)
21065
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    31
    if version == '10':
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    32
        if alg is None:
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    33
            alg = changegroup.readexactly(fh, 2)
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22354
diff changeset
    34
        return changegroup.cg1unpacker(fh, alg)
23009
90f86ad3d4ff bundle2: change header size and make them signed (new format)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23000
diff changeset
    35
    elif version == '2Y':
21067
7974aa88868e bundle2: let readbundle return unbundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21065
diff changeset
    36
        return bundle2.unbundle20(ui, fh, header=magic + version)
21065
f9a9a6d63e89 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
    37
    else:
21063
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    38
        raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
7ca4f2049d3b bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21062
diff changeset
    39
22346
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    40
def buildobsmarkerspart(bundler, markers):
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    41
    """add an obsmarker part to the bundler with <markers>
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    42
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    43
    No part is created if markers is empty.
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    44
    Raises ValueError if the bundler doesn't support any known obsmarker format.
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    45
    """
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    46
    if markers:
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    47
        remoteversions = bundle2.obsmarkersversion(bundler.capabilities)
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    48
        version = obsolete.commonversion(remoteversions)
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    49
        if version is None:
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    50
            raise ValueError('bundler do not support common obsmarker format')
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    51
        stream = obsolete.encodemarkers(markers, True, version=version)
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    52
        return bundler.newpart('B2X:OBSMARKERS', data=stream)
a76660f85200 exchange: add a `buildobsmarkerpart` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
    53
    return None
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    54
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    55
class pushoperation(object):
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    56
    """A object that represent a single push operation
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    57
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    58
    It purpose is to carry push related state and very common operation.
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    59
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
    60
    A new should be created at the beginning of each push and discarded
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    61
    afterward.
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    62
    """
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    63
22623
cd7e17aa6040 push: pass list of bookmark to `exchange.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22622
diff changeset
    64
    def __init__(self, repo, remote, force=False, revs=None, newbranch=False,
cd7e17aa6040 push: pass list of bookmark to `exchange.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22622
diff changeset
    65
                 bookmarks=()):
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    66
        # repo we push from
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
    67
        self.repo = repo
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
    68
        self.ui = repo.ui
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
    69
        # repo we push to
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
    70
        self.remote = remote
20349
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
    71
        # force option provided
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
    72
        self.force = force
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
    73
        # revs to be pushed (None is "all")
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
    74
        self.revs = revs
22623
cd7e17aa6040 push: pass list of bookmark to `exchange.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22622
diff changeset
    75
        # bookmark explicitly pushed
cd7e17aa6040 push: pass list of bookmark to `exchange.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22622
diff changeset
    76
        self.bookmarks = bookmarks
20351
c05ad450df23 push: move `newbranch` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20350
diff changeset
    77
        # allow push of new branch
c05ad450df23 push: move `newbranch` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20350
diff changeset
    78
        self.newbranch = newbranch
20436
2f2e8d1c4856 push: move local lock logic in pushoperation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20435
diff changeset
    79
        # did a local lock get acquired?
2f2e8d1c4856 push: move local lock logic in pushoperation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20435
diff changeset
    80
        self.locallocked = None
21901
8612c4ab7f54 push: add a ``pushop.stepsdone`` attribute
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21899
diff changeset
    81
        # step already performed
8612c4ab7f54 push: add a ``pushop.stepsdone`` attribute
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21899
diff changeset
    82
        # (used to check what steps have been already performed through bundle2)
8612c4ab7f54 push: add a ``pushop.stepsdone`` attribute
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21899
diff changeset
    83
        self.stepsdone = set()
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
    84
        # Integer version of the changegroup push result
20439
0d3ccf285ff2 push: move push return value in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20438
diff changeset
    85
        # - None means nothing to push
0d3ccf285ff2 push: move push return value in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20438
diff changeset
    86
        # - 0 means HTTP error
0d3ccf285ff2 push: move push return value in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20438
diff changeset
    87
        # - 1 means we pushed and remote head count is unchanged *or*
0d3ccf285ff2 push: move push return value in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20438
diff changeset
    88
        #   we have outgoing changesets but refused to push
0d3ccf285ff2 push: move push return value in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20438
diff changeset
    89
        # - other values as described by addchangegroup()
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
    90
        self.cgresult = None
22624
eef31f9a4c0f push: add `pushoperation.bkresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22623
diff changeset
    91
        # Boolean value for the bookmark push
eef31f9a4c0f push: add `pushoperation.bkresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22623
diff changeset
    92
        self.bkresult = None
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
    93
        # discover.outgoing object (contains common and outgoing data)
20440
400da8bc7786 push: move outgoing object in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20439
diff changeset
    94
        self.outgoing = None
20462
0031ef5df586 push: move `remoteheads` into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20441
diff changeset
    95
        # all remote heads before the push
0031ef5df586 push: move `remoteheads` into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20441
diff changeset
    96
        self.remoteheads = None
20464
d032417db243 push: move `incoming` into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20463
diff changeset
    97
        # testable as a boolean indicating if any nodes are missing locally.
d032417db243 push: move `incoming` into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20463
diff changeset
    98
        self.incoming = None
22019
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
    99
        # phases changes that must be pushed along side the changesets
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   100
        self.outdatedphases = None
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   101
        # phases changes that must be pushed if changeset push fails
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   102
        self.fallbackoutdatedphases = None
22034
5f57bc77657c push: move the list of obsmarker to push into the push operation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22033
diff changeset
   103
        # outgoing obsmarkers
22035
24bb01f42e82 push: introduce a discovery step for obsmarker
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22034
diff changeset
   104
        self.outobsmarkers = set()
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   105
        # outgoing bookmarks
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   106
        self.outbookmarks = []
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
   107
22014
71083b020b4a push: extract future heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21989
diff changeset
   108
    @util.propertycache
71083b020b4a push: extract future heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21989
diff changeset
   109
    def futureheads(self):
71083b020b4a push: extract future heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21989
diff changeset
   110
        """future remote heads if the changeset push succeeds"""
71083b020b4a push: extract future heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21989
diff changeset
   111
        return self.outgoing.missingheads
71083b020b4a push: extract future heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21989
diff changeset
   112
22015
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   113
    @util.propertycache
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   114
    def fallbackheads(self):
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   115
        """future remote heads if the changeset push fails"""
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   116
        if self.revs is None:
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   117
            # not target to push, all common are relevant
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   118
            return self.outgoing.commonheads
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   119
        unfi = self.repo.unfiltered()
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   120
        # I want cheads = heads(::missingheads and ::commonheads)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   121
        # (missingheads is revs with secret changeset filtered out)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   122
        #
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   123
        # This can be expressed as:
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   124
        #     cheads = ( (missingheads and ::commonheads)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   125
        #              + (commonheads and ::missingheads))"
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   126
        #              )
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   127
        #
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   128
        # while trying to push we already computed the following:
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   129
        #     common = (::commonheads)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   130
        #     missing = ((commonheads::missingheads) - commonheads)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   131
        #
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   132
        # We can pick:
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   133
        # * missingheads part of common (::commonheads)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   134
        common = set(self.outgoing.common)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   135
        nm = self.repo.changelog.nodemap
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   136
        cheads = [node for node in self.revs if nm[node] in common]
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   137
        # and
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   138
        # * commonheads parents on missing
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   139
        revset = unfi.set('%ln and parents(roots(%ln))',
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   140
                         self.outgoing.commonheads,
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   141
                         self.outgoing.missing)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   142
        cheads.extend(c.node() for c in revset)
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   143
        return cheads
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   144
22016
7d976d71684c push: move common heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22015
diff changeset
   145
    @property
7d976d71684c push: move common heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22015
diff changeset
   146
    def commonheads(self):
7d976d71684c push: move common heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22015
diff changeset
   147
        """set of all common heads after changeset bundle push"""
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   148
        if self.cgresult:
22016
7d976d71684c push: move common heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22015
diff changeset
   149
            return self.futureheads
7d976d71684c push: move common heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22015
diff changeset
   150
        else:
7d976d71684c push: move common heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22015
diff changeset
   151
            return self.fallbackheads
22015
c478031deba2 push: extract fallback heads computation into pushop
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22014
diff changeset
   152
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   153
# mapping of message used when pushing bookmark
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   154
bookmsgmap = {'update': (_("updating bookmark %s\n"),
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   155
                         _('updating bookmark %s failed!\n')),
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   156
              'export': (_("exporting bookmark %s\n"),
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   157
                         _('exporting bookmark %s failed!\n')),
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   158
              'delete': (_("deleting remote bookmark %s\n"),
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   159
                         _('deleting remote bookmark %s failed!\n')),
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   160
              }
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   161
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   162
22623
cd7e17aa6040 push: pass list of bookmark to `exchange.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22622
diff changeset
   163
def push(repo, remote, force=False, revs=None, newbranch=False, bookmarks=()):
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   164
    '''Push outgoing changesets (limited by revs) from a local
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   165
    repository to remote. Return an integer:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   166
      - None means nothing to push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   167
      - 0 means HTTP error
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   168
      - 1 means we pushed and remote head count is unchanged *or*
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   169
        we have outgoing changesets but refused to push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   170
      - other values as described by addchangegroup()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   171
    '''
22623
cd7e17aa6040 push: pass list of bookmark to `exchange.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22622
diff changeset
   172
    pushop = pushoperation(repo, remote, force, revs, newbranch, bookmarks)
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
   173
    if pushop.remote.local():
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
   174
        missing = (set(pushop.repo.requirements)
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
   175
                   - pushop.remote.local().supported)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   176
        if missing:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   177
            msg = _("required features are not"
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   178
                    " supported in the destination:"
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   179
                    " %s") % (', '.join(sorted(missing)))
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   180
            raise util.Abort(msg)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   181
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   182
    # there are two ways to push to remote repo:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   183
    #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   184
    # addchangegroup assumes local user can lock remote
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   185
    # repo (local filesystem, old ssh servers).
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   186
    #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   187
    # unbundle assumes local user cannot lock remote repo (new ssh
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   188
    # servers, http servers).
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   189
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
   190
    if not pushop.remote.canpush():
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   191
        raise util.Abort(_("destination does not support push"))
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   192
    # get local lock as we might write phase data
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   193
    locallock = None
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   194
    try:
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
   195
        locallock = pushop.repo.lock()
20436
2f2e8d1c4856 push: move local lock logic in pushoperation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20435
diff changeset
   196
        pushop.locallocked = True
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   197
    except IOError, err:
20436
2f2e8d1c4856 push: move local lock logic in pushoperation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20435
diff changeset
   198
        pushop.locallocked = False
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   199
        if err.errno != errno.EACCES:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   200
            raise
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   201
        # source repo cannot be locked.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   202
        # We do not abort the push, but just disable the local phase
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   203
        # synchronisation.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   204
        msg = 'cannot lock source repository: %s\n' % err
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
   205
        pushop.ui.debug(msg)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   206
    try:
20924
e10000369b47 push: pass a `pushoperation` object to localrepo.checkpush
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20901
diff changeset
   207
        pushop.repo.checkpush(pushop)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   208
        lock = None
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
   209
        unbundle = pushop.remote.capable('unbundle')
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   210
        if not unbundle:
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
   211
            lock = pushop.remote.lock()
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   212
        try:
20466
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   213
            _pushdiscovery(pushop)
21903
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   214
            if (pushop.repo.ui.configbool('experimental', 'bundle2-exp',
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   215
                                          False)
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   216
                and pushop.remote.capable('bundle2-exp')):
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   217
                _pushbundle2(pushop)
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   218
            _pushchangeset(pushop)
20441
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   219
            _pushsyncphase(pushop)
20433
6af248474224 push: feed pushoperation object to _pushobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20432
diff changeset
   220
            _pushobsolete(pushop)
22224
f713de1d3916 push: update bookmarks within the remote lock
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22069
diff changeset
   221
            _pushbookmark(pushop)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   222
        finally:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   223
            if lock is not None:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   224
                lock.release()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   225
    finally:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   226
        if locallock is not None:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   227
            locallock.release()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   228
22616
cda85cfc8252 push: `exchange.push` now returns the `pushoperation` object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22615
diff changeset
   229
    return pushop
20352
58300f61b139 push: move bookmarks exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20351
diff changeset
   230
22018
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   231
# list of steps to perform discovery before push
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   232
pushdiscoveryorder = []
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   233
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   234
# Mapping between step name and function
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   235
#
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   236
# This exists to help extensions wrap steps if necessary
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   237
pushdiscoverymapping = {}
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   238
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   239
def pushdiscovery(stepname):
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   240
    """decorator for function performing discovery before push
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   241
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   242
    The function is added to the step -> function mapping and appended to the
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   243
    list of steps.  Beware that decorated function will be added in order (this
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   244
    may matter).
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   245
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   246
    You can only use this decorator for a new step, if you want to wrap a step
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   247
    from an extension, change the pushdiscovery dictionary directly."""
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   248
    def dec(func):
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   249
        assert stepname not in pushdiscoverymapping
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   250
        pushdiscoverymapping[stepname] = func
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   251
        pushdiscoveryorder.append(stepname)
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   252
        return func
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   253
    return dec
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   254
20466
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   255
def _pushdiscovery(pushop):
22018
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   256
    """Run all discovery steps"""
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   257
    for stepname in pushdiscoveryorder:
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   258
        step = pushdiscoverymapping[stepname]
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   259
        step(pushop)
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   260
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   261
@pushdiscovery('changeset')
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   262
def _pushdiscoverychangeset(pushop):
ddb56e7e1b92 push: make discovery extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22017
diff changeset
   263
    """discover the changeset that need to be pushed"""
20466
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   264
    unfi = pushop.repo.unfiltered()
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   265
    fci = discovery.findcommonincoming
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   266
    commoninc = fci(unfi, pushop.remote, force=pushop.force)
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   267
    common, inc, remoteheads = commoninc
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   268
    fco = discovery.findcommonoutgoing
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   269
    outgoing = fco(unfi, pushop.remote, onlyheads=pushop.revs,
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   270
                   commoninc=commoninc, force=pushop.force)
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   271
    pushop.outgoing = outgoing
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   272
    pushop.remoteheads = remoteheads
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   273
    pushop.incoming = inc
233623d58c9a push: move discovery in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20465
diff changeset
   274
22019
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   275
@pushdiscovery('phase')
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   276
def _pushdiscoveryphase(pushop):
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   277
    """discover the phase that needs to be pushed
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   278
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   279
    (computed for both success and failure case for changesets push)"""
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   280
    outgoing = pushop.outgoing
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   281
    unfi = pushop.repo.unfiltered()
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   282
    remotephases = pushop.remote.listkeys('phases')
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   283
    publishing = remotephases.get('publishing', False)
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   284
    ana = phases.analyzeremotephases(pushop.repo,
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   285
                                     pushop.fallbackheads,
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   286
                                     remotephases)
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   287
    pheads, droots = ana
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   288
    extracond = ''
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   289
    if not publishing:
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   290
        extracond = ' and public()'
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   291
    revset = 'heads((%%ln::%%ln) %s)' % extracond
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   292
    # Get the list of all revs draft on remote by public here.
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   293
    # XXX Beware that revset break if droots is not strictly
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   294
    # XXX root we may want to ensure it is but it is costly
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   295
    fallback = list(unfi.set(revset, droots, pushop.fallbackheads))
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   296
    if not outgoing.missing:
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   297
        future = fallback
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   298
    else:
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   299
        # adds changeset we are going to push as draft
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   300
        #
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23082
diff changeset
   301
        # should not be necessary for publishing server, but because of an
22019
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   302
        # issue fixed in xxxxx we have to do it anyway.
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   303
        fdroots = list(unfi.set('roots(%ln  + %ln::)',
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   304
                       outgoing.missing, droots))
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   305
        fdroots = [f.node() for f in fdroots]
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   306
        future = list(unfi.set(revset, fdroots, pushop.futureheads))
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   307
    pushop.outdatedphases = future
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   308
    pushop.fallbackoutdatedphases = fallback
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   309
22035
24bb01f42e82 push: introduce a discovery step for obsmarker
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22034
diff changeset
   310
@pushdiscovery('obsmarker')
24bb01f42e82 push: introduce a discovery step for obsmarker
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22034
diff changeset
   311
def _pushdiscoveryobsmarkers(pushop):
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 22937
diff changeset
   312
    if (obsolete.isenabled(pushop.repo, obsolete.exchangeopt)
22269
03cc81a28228 push: check if local and remote support evolution during discovery
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22244
diff changeset
   313
        and pushop.repo.obsstore
03cc81a28228 push: check if local and remote support evolution during discovery
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22244
diff changeset
   314
        and 'obsolete' in pushop.remote.listkeys('namespaces')):
22350
6d113cc7a31a push: only push obsmarkers relevant to the "pushed subset"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22347
diff changeset
   315
        repo = pushop.repo
6d113cc7a31a push: only push obsmarkers relevant to the "pushed subset"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22347
diff changeset
   316
        # very naive computation, that can be quite expensive on big repo.
6d113cc7a31a push: only push obsmarkers relevant to the "pushed subset"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22347
diff changeset
   317
        # However: evolution is currently slow on them anyway.
6d113cc7a31a push: only push obsmarkers relevant to the "pushed subset"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22347
diff changeset
   318
        nodes = (c.node() for c in repo.set('::%ln', pushop.futureheads))
6d113cc7a31a push: only push obsmarkers relevant to the "pushed subset"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22347
diff changeset
   319
        pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes)
22035
24bb01f42e82 push: introduce a discovery step for obsmarker
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22034
diff changeset
   320
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   321
@pushdiscovery('bookmarks')
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   322
def _pushdiscoverybookmarks(pushop):
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   323
    ui = pushop.ui
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   324
    repo = pushop.repo.unfiltered()
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   325
    remote = pushop.remote
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   326
    ui.debug("checking for updated bookmarks\n")
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   327
    ancestors = ()
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   328
    if pushop.revs:
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   329
        revnums = map(repo.changelog.rev, pushop.revs)
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   330
        ancestors = repo.changelog.ancestors(revnums, inclusive=True)
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   331
    remotebookmark = remote.listkeys('bookmarks')
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   332
22651
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   333
    explicit = set(pushop.bookmarks)
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   334
22622
ce6b9edee725 exchange: import bookmarks as bookmod
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22616
diff changeset
   335
    comp = bookmod.compare(repo, repo._bookmarks, remotebookmark, srchex=hex)
23081
e62c330a044f bookmarks: explicitly track identical bookmarks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23047
diff changeset
   336
    addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = comp
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   337
    for b, scid, dcid in advsrc:
22651
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   338
        if b in explicit:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   339
            explicit.remove(b)
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   340
        if not ancestors or repo[scid].rev() in ancestors:
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   341
            pushop.outbookmarks.append((b, dcid, scid))
22651
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   342
    # search added bookmark
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   343
    for b, scid, dcid in addsrc:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   344
        if b in explicit:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   345
            explicit.remove(b)
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   346
            pushop.outbookmarks.append((b, '', scid))
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   347
    # search for overwritten bookmark
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   348
    for b, scid, dcid in advdst + diverge + differ:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   349
        if b in explicit:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   350
            explicit.remove(b)
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   351
            pushop.outbookmarks.append((b, dcid, scid))
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   352
    # search for bookmark to delete
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   353
    for b, scid, dcid in adddst:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   354
        if b in explicit:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   355
            explicit.remove(b)
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   356
            # treat as "deleted locally"
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   357
            pushop.outbookmarks.append((b, dcid, ''))
23082
0fc4686de1d7 exchange: don't report failure from identical bookmarks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23081
diff changeset
   358
    # identical bookmarks shouldn't get reported
0fc4686de1d7 exchange: don't report failure from identical bookmarks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23081
diff changeset
   359
    for b, scid, dcid in same:
0fc4686de1d7 exchange: don't report failure from identical bookmarks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23081
diff changeset
   360
        if b in explicit:
0fc4686de1d7 exchange: don't report failure from identical bookmarks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23081
diff changeset
   361
            explicit.remove(b)
22651
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   362
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   363
    if explicit:
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   364
        explicit = sorted(explicit)
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   365
        # we should probably list all of them
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   366
        ui.warn(_('bookmark %s does not exist on the local '
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   367
                  'or remote repository!\n') % explicit[0])
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   368
        pushop.bkresult = 2
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   369
b901645a8784 push: gather all bookmark decisions together
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22650
diff changeset
   370
    pushop.outbookmarks.sort()
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   371
20465
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   372
def _pushcheckoutgoing(pushop):
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   373
    outgoing = pushop.outgoing
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   374
    unfi = pushop.repo.unfiltered()
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   375
    if not outgoing.missing:
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   376
        # nothing to push
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   377
        scmutil.nochangesfound(unfi.ui, unfi, outgoing.excluded)
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   378
        return False
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   379
    # something to push
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   380
    if not pushop.force:
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   381
        # if repo.obsstore == False --> no obsolete
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   382
        # then, save the iteration
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   383
        if unfi.obsstore:
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   384
            # this message are here for 80 char limit reason
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   385
            mso = _("push includes obsolete changeset: %s!")
22628
2805d23e1f88 exchange: remove a broken i18n abuse
Matt Mackall <mpm@selenic.com>
parents: 22625
diff changeset
   386
            mst = {"unstable": _("push includes unstable changeset: %s!"),
2805d23e1f88 exchange: remove a broken i18n abuse
Matt Mackall <mpm@selenic.com>
parents: 22625
diff changeset
   387
                   "bumped": _("push includes bumped changeset: %s!"),
2805d23e1f88 exchange: remove a broken i18n abuse
Matt Mackall <mpm@selenic.com>
parents: 22625
diff changeset
   388
                   "divergent": _("push includes divergent changeset: %s!")}
20465
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   389
            # If we are to push if there is at least one
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   390
            # obsolete or unstable changeset in missing, at
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   391
            # least one of the missinghead will be obsolete or
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   392
            # unstable. So checking heads only is ok
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   393
            for node in outgoing.missingheads:
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   394
                ctx = unfi[node]
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   395
                if ctx.obsolete():
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   396
                    raise util.Abort(mso % ctx)
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   397
                elif ctx.troubled():
22628
2805d23e1f88 exchange: remove a broken i18n abuse
Matt Mackall <mpm@selenic.com>
parents: 22625
diff changeset
   398
                    raise util.Abort(mst[ctx.troubles()[0]] % ctx)
20465
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   399
        newbm = pushop.ui.configlist('bookmarks', 'pushing')
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   400
        discovery.checkheads(unfi, pushop.remote, outgoing,
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   401
                             pushop.remoteheads,
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   402
                             pushop.newbranch,
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   403
                             bool(pushop.incoming),
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   404
                             newbm)
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   405
    return True
170f71061069 push: move outgoing check logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20464
diff changeset
   406
22017
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   407
# List of names of steps to perform for an outgoing bundle2, order matters.
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   408
b2partsgenorder = []
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   409
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   410
# Mapping between step name and function
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   411
#
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   412
# This exists to help extensions wrap steps if necessary
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   413
b2partsgenmapping = {}
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   414
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   415
def b2partsgenerator(stepname):
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   416
    """decorator for function generating bundle2 part
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   417
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   418
    The function is added to the step -> function mapping and appended to the
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   419
    list of steps.  Beware that decorated functions will be added in order
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   420
    (this may matter).
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   421
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   422
    You can only use this decorator for new steps, if you want to wrap a step
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   423
    from an extension, attack the b2partsgenmapping dictionary directly."""
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   424
    def dec(func):
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   425
        assert stepname not in b2partsgenmapping
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   426
        b2partsgenmapping[stepname] = func
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   427
        b2partsgenorder.append(stepname)
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   428
        return func
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   429
    return dec
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   430
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   431
@b2partsgenerator('changeset')
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   432
def _pushb2ctx(pushop, bundler):
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   433
    """handle changegroup push through bundle2
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   434
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   435
    addchangegroup result is stored in the ``pushop.cgresult`` attribute.
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   436
    """
21902
7a7def851ba0 push: use `stepsdone` to control changegroup push through bundle10 or bundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21901
diff changeset
   437
    if 'changesets' in pushop.stepsdone:
7a7def851ba0 push: use `stepsdone` to control changegroup push through bundle10 or bundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21901
diff changeset
   438
        return
7a7def851ba0 push: use `stepsdone` to control changegroup push through bundle10 or bundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21901
diff changeset
   439
    pushop.stepsdone.add('changesets')
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   440
    # Send known heads to the server for race detection.
21903
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   441
    if not _pushcheckoutgoing(pushop):
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   442
        return
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   443
    pushop.repo.prepushoutgoinghooks(pushop.repo,
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   444
                                     pushop.remote,
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   445
                                     pushop.outgoing)
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   446
    if not pushop.force:
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   447
        bundler.newpart('B2X:CHECK:HEADS', data=iter(pushop.remoteheads))
23180
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   448
    b2caps = bundle2.bundle2caps(pushop.remote)
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   449
    version = None
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   450
    cgversions = b2caps.get('b2x:changegroup')
23208
f606e07fa148 bundle2: handle empty 'b2x:changegroup' value in push and pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23203
diff changeset
   451
    if not cgversions:  # 3.1 and 3.2 ship with an empty value
23180
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   452
        cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push',
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   453
                                                pushop.outgoing)
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   454
    else:
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   455
        cgversions = [v for v in cgversions if v in changegroup.packermap]
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   456
        if not cgversions:
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   457
            raise ValueError(_('no common changegroup version'))
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   458
        version = max(cgversions)
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   459
        cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push',
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   460
                                                pushop.outgoing,
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   461
                                                version=version)
23177
706547a14b8b changegroup: introduce "raw" versions of some commands
Sune Foldager <cryo@cyanite.org>
parents: 23139
diff changeset
   462
    cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg)
23180
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   463
    if version is not None:
116b80d63815 push: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23179
diff changeset
   464
        cgpart.addparam('version', version)
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   465
    def handlereply(op):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23082
diff changeset
   466
        """extract addchangegroup returns from server reply"""
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   467
        cgreplies = op.records.getreplies(cgpart.id)
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   468
        assert len(cgreplies['changegroup']) == 1
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   469
        pushop.cgresult = cgreplies['changegroup'][0]['return']
21899
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   470
    return handlereply
52ab44b979f4 bundle2-push: extract changegroup logic in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21898
diff changeset
   471
22020
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   472
@b2partsgenerator('phase')
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   473
def _pushb2phases(pushop, bundler):
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   474
    """handle phase push through bundle2"""
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   475
    if 'phases' in pushop.stepsdone:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   476
        return
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   477
    b2caps = bundle2.bundle2caps(pushop.remote)
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   478
    if not 'b2x:pushkey' in b2caps:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   479
        return
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   480
    pushop.stepsdone.add('phases')
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   481
    part2node = []
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   482
    enc = pushkey.encode
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   483
    for newremotehead in pushop.outdatedphases:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   484
        part = bundler.newpart('b2x:pushkey')
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   485
        part.addparam('namespace', enc('phases'))
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   486
        part.addparam('key', enc(newremotehead.hex()))
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   487
        part.addparam('old', enc(str(phases.draft)))
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   488
        part.addparam('new', enc(str(phases.public)))
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   489
        part2node.append((part.id, newremotehead))
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   490
    def handlereply(op):
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   491
        for partid, node in part2node:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   492
            partrep = op.records.getreplies(partid)
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   493
            results = partrep['pushkey']
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   494
            assert len(results) <= 1
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   495
            msg = None
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   496
            if not results:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   497
                msg = _('server ignored update of %s to public!\n') % node
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   498
            elif not int(results[0]['return']):
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   499
                msg = _('updating %s to public failed!\n') % node
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   500
            if msg is not None:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   501
                pushop.ui.warn(msg)
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   502
    return handlereply
21904
5fbccbcc07ea bundle2-push: introduce a list of part generating functions
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21903
diff changeset
   503
22347
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   504
@b2partsgenerator('obsmarkers')
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   505
def _pushb2obsmarkers(pushop, bundler):
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   506
    if 'obsmarkers' in pushop.stepsdone:
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   507
        return
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   508
    remoteversions = bundle2.obsmarkersversion(bundler.capabilities)
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   509
    if obsolete.commonversion(remoteversions) is None:
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   510
        return
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   511
    pushop.stepsdone.add('obsmarkers')
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   512
    if pushop.outobsmarkers:
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   513
        buildobsmarkerspart(bundler, pushop.outobsmarkers)
7198cb9b56b9 push: use bundle2 to push obsmarkers when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22346
diff changeset
   514
22242
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   515
@b2partsgenerator('bookmarks')
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   516
def _pushb2bookmarks(pushop, bundler):
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   517
    """handle phase push through bundle2"""
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   518
    if 'bookmarks' in pushop.stepsdone:
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   519
        return
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   520
    b2caps = bundle2.bundle2caps(pushop.remote)
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   521
    if 'b2x:pushkey' not in b2caps:
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   522
        return
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   523
    pushop.stepsdone.add('bookmarks')
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   524
    part2book = []
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   525
    enc = pushkey.encode
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   526
    for book, old, new in pushop.outbookmarks:
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   527
        part = bundler.newpart('b2x:pushkey')
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   528
        part.addparam('namespace', enc('bookmarks'))
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   529
        part.addparam('key', enc(book))
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   530
        part.addparam('old', enc(old))
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   531
        part.addparam('new', enc(new))
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   532
        action = 'update'
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   533
        if not old:
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   534
            action = 'export'
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   535
        elif not new:
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   536
            action = 'delete'
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   537
        part2book.append((part.id, book, action))
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   538
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   539
22242
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   540
    def handlereply(op):
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   541
        ui = pushop.ui
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   542
        for partid, book, action in part2book:
22242
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   543
            partrep = op.records.getreplies(partid)
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   544
            results = partrep['pushkey']
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   545
            assert len(results) <= 1
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   546
            if not results:
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   547
                pushop.ui.warn(_('server ignored bookmark %s update\n') % book)
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   548
            else:
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   549
                ret = int(results[0]['return'])
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   550
                if ret:
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   551
                    ui.status(bookmsgmap[action][0] % book)
22242
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   552
                else:
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   553
                    ui.warn(bookmsgmap[action][1] % book)
22649
1d7a2422b90c push: set bkresult when pushing bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22645
diff changeset
   554
                    if pushop.bkresult is not None:
1d7a2422b90c push: set bkresult when pushing bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22645
diff changeset
   555
                        pushop.bkresult = 1
22242
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   556
    return handlereply
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   557
ed222ebd61be push: add bookmarks to the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22240
diff changeset
   558
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   559
def _pushbundle2(pushop):
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   560
    """push data to the remote using bundle2
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   561
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   562
    The only currently supported type of data is changegroup but this will
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   563
    evolve in the future."""
21644
17755dd8c509 bundle2: introduce a bundle2caps function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21643
diff changeset
   564
    bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote))
21142
15039ce3e4a3 bundle2: include client capabilities in the pushed bundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21141
diff changeset
   565
    # create reply capability
22342
262c5cc126c1 bundle2: introduce a `getrepocaps` to retrieve the bundle2 caps of a repo
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22341
diff changeset
   566
    capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo))
21600
5e08f3b65510 bundle2: update all ``addpart`` callers to ``newpart``
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21555
diff changeset
   567
    bundler.newpart('b2x:replycaps', data=capsblob)
21904
5fbccbcc07ea bundle2-push: introduce a list of part generating functions
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21903
diff changeset
   568
    replyhandlers = []
22017
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   569
    for partgenname in b2partsgenorder:
7986e99bb69a push: rework the bundle2partsgenerators logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22016
diff changeset
   570
        partgen = b2partsgenmapping[partgenname]
21904
5fbccbcc07ea bundle2-push: introduce a list of part generating functions
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21903
diff changeset
   571
        ret = partgen(pushop, bundler)
21941
dab31290c7eb bundle2: only use callable return as reply handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21906
diff changeset
   572
        if callable(ret):
dab31290c7eb bundle2: only use callable return as reply handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21906
diff changeset
   573
            replyhandlers.append(ret)
21904
5fbccbcc07ea bundle2-push: introduce a list of part generating functions
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21903
diff changeset
   574
    # do not push if nothing to push
21903
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   575
    if bundler.nbparts <= 1:
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   576
        return
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   577
    stream = util.chunkbuffer(bundler.getchunks())
21182
08c84fd99aac bundle2: catch UnknownPartError during local push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21181
diff changeset
   578
    try:
08c84fd99aac bundle2: catch UnknownPartError during local push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21181
diff changeset
   579
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
21618
7568f5c1c801 bundle2: move exception classes into the error module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21617
diff changeset
   580
    except error.BundleValueError, exc:
21182
08c84fd99aac bundle2: catch UnknownPartError during local push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21181
diff changeset
   581
        raise util.Abort('missing support for %s' % exc)
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   582
    try:
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   583
        op = bundle2.processbundle(pushop.repo, reply)
21618
7568f5c1c801 bundle2: move exception classes into the error module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21617
diff changeset
   584
    except error.BundleValueError, exc:
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   585
        raise util.Abort('missing support for %s' % exc)
21904
5fbccbcc07ea bundle2-push: introduce a list of part generating functions
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21903
diff changeset
   586
    for rephand in replyhandlers:
5fbccbcc07ea bundle2-push: introduce a list of part generating functions
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21903
diff changeset
   587
        rephand(op)
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
   588
20463
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   589
def _pushchangeset(pushop):
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   590
    """Make the actual push of changeset bundle to remote repo"""
21902
7a7def851ba0 push: use `stepsdone` to control changegroup push through bundle10 or bundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21901
diff changeset
   591
    if 'changesets' in pushop.stepsdone:
7a7def851ba0 push: use `stepsdone` to control changegroup push through bundle10 or bundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21901
diff changeset
   592
        return
7a7def851ba0 push: use `stepsdone` to control changegroup push through bundle10 or bundle20
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21901
diff changeset
   593
    pushop.stepsdone.add('changesets')
21903
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   594
    if not _pushcheckoutgoing(pushop):
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   595
        return
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   596
    pushop.repo.prepushoutgoinghooks(pushop.repo,
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   597
                                     pushop.remote,
48f61cfb7576 bundle2-push: move changegroup push validation inside _pushb2ctx
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21902
diff changeset
   598
                                     pushop.outgoing)
20463
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   599
    outgoing = pushop.outgoing
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   600
    unbundle = pushop.remote.capable('unbundle')
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   601
    # TODO: get bundlecaps from remote
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   602
    bundlecaps = None
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   603
    # create a changegroup from local
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   604
    if pushop.revs is None and not (outgoing.excluded
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   605
                            or pushop.repo.changelog.filteredrevs):
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   606
        # push everything,
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   607
        # use the fast path, no race possible on push
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22354
diff changeset
   608
        bundler = changegroup.cg1packer(pushop.repo, bundlecaps)
20925
5174c48ed8d8 localrepo: move the _changegroupsubset method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20924
diff changeset
   609
        cg = changegroup.getsubset(pushop.repo,
5174c48ed8d8 localrepo: move the _changegroupsubset method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20924
diff changeset
   610
                                   outgoing,
5174c48ed8d8 localrepo: move the _changegroupsubset method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20924
diff changeset
   611
                                   bundler,
5174c48ed8d8 localrepo: move the _changegroupsubset method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20924
diff changeset
   612
                                   'push',
5174c48ed8d8 localrepo: move the _changegroupsubset method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20924
diff changeset
   613
                                   fastpath=True)
20463
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   614
    else:
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22354
diff changeset
   615
        cg = changegroup.getlocalchangegroup(pushop.repo, 'push', outgoing,
20928
91b47139d0cb localrepo: move the getlocalbundle method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20925
diff changeset
   616
                                        bundlecaps)
20463
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   617
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   618
    # apply changegroup to remote
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   619
    if unbundle:
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   620
        # local repo finds heads on server, finds out what
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   621
        # revs it must push. once revs transferred, if server
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   622
        # finds it has different heads (someone else won
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   623
        # commit/push race), server aborts.
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   624
        if pushop.force:
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   625
            remoteheads = ['force']
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   626
        else:
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   627
            remoteheads = pushop.remoteheads
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   628
        # ssh: return remote's addchangegroup()
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   629
        # http: return remote's addchangegroup() or 0 for error
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   630
        pushop.cgresult = pushop.remote.unbundle(cg, remoteheads,
21761
b2dc026a9bd2 push: restore contents of HG_URL for hooks (issue4268)
Matt Mackall <mpm@selenic.com>
parents: 21259
diff changeset
   631
                                            pushop.repo.url())
20463
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   632
    else:
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   633
        # we return an integer indicating remote head count
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   634
        # change
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   635
        pushop.cgresult = pushop.remote.addchangegroup(cg, 'push',
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   636
                                                       pushop.repo.url())
20463
f1b532a310e4 push: move changeset push logic in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20462
diff changeset
   637
20441
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   638
def _pushsyncphase(pushop):
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
   639
    """synchronise phase information locally and remotely"""
20468
7d0bbb6dd730 push: extract new common set computation from phase synchronisation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20467
diff changeset
   640
    cheads = pushop.commonheads
20441
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   641
    # even when we don't push, exchanging phase data is useful
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   642
    remotephases = pushop.remote.listkeys('phases')
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   643
    if (pushop.ui.configbool('ui', '_usedassubrepo', False)
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   644
        and remotephases    # server supports phases
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   645
        and pushop.cgresult is None # nothing was pushed
20441
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   646
        and remotephases.get('publishing', False)):
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   647
        # When:
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   648
        # - this is a subrepo push
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   649
        # - and remote support phase
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   650
        # - and no changeset was pushed
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   651
        # - and remote is publishing
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   652
        # We may be in issue 3871 case!
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   653
        # We drop the possible phase synchronisation done by
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   654
        # courtesy to publish changesets possibly locally draft
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   655
        # on the remote.
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   656
        remotephases = {'publishing': 'True'}
21012
c827a0028e6f exchange: restore truncated comment
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21005
diff changeset
   657
    if not remotephases: # old server or public only reply from non-publishing
20441
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   658
        _localphasemove(pushop, cheads)
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   659
        # don't push any phase data as there is nothing to push
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   660
    else:
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   661
        ana = phases.analyzeremotephases(pushop.repo, cheads,
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   662
                                         remotephases)
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   663
        pheads, droots = ana
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   664
        ### Apply remote phase on local
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   665
        if remotephases.get('publishing', False):
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   666
            _localphasemove(pushop, cheads)
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   667
        else: # publish = False
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   668
            _localphasemove(pushop, pheads)
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   669
            _localphasemove(pushop, cheads, phases.draft)
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   670
        ### Apply local phase on remote
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   671
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   672
        if pushop.cgresult:
22020
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   673
            if 'phases' in pushop.stepsdone:
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   674
                # phases already pushed though bundle2
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   675
                return
22019
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   676
            outdated = pushop.outdatedphases
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   677
        else:
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   678
            outdated = pushop.fallbackoutdatedphases
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   679
22020
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   680
        pushop.stepsdone.add('phases')
311979b773fb push: include phase push in the unified bundle2 push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22019
diff changeset
   681
22019
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   682
        # filter heads already turned public by the push
9fcf772f15ff push: perform phases discovery before the push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22018
diff changeset
   683
        outdated = [c for c in outdated if c.node() not in pheads]
21662
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   684
        b2caps = bundle2.bundle2caps(pushop.remote)
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   685
        if 'b2x:pushkey' in b2caps:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   686
            # server supports bundle2, let's do a batched push through it
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   687
            #
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   688
            # This will eventually be unified with the changesets bundle2 push
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   689
            bundler = bundle2.bundle20(pushop.ui, b2caps)
22342
262c5cc126c1 bundle2: introduce a `getrepocaps` to retrieve the bundle2 caps of a repo
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22341
diff changeset
   690
            capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo))
21662
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   691
            bundler.newpart('b2x:replycaps', data=capsblob)
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   692
            part2node = []
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   693
            enc = pushkey.encode
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   694
            for newremotehead in outdated:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   695
                part = bundler.newpart('b2x:pushkey')
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   696
                part.addparam('namespace', enc('phases'))
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   697
                part.addparam('key', enc(newremotehead.hex()))
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   698
                part.addparam('old', enc(str(phases.draft)))
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   699
                part.addparam('new', enc(str(phases.public)))
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   700
                part2node.append((part.id, newremotehead))
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   701
            stream = util.chunkbuffer(bundler.getchunks())
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   702
            try:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   703
                reply = pushop.remote.unbundle(stream, ['force'], 'push')
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   704
                op = bundle2.processbundle(pushop.repo, reply)
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   705
            except error.BundleValueError, exc:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   706
                raise util.Abort('missing support for %s' % exc)
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   707
            for partid, node in part2node:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   708
                partrep = op.records.getreplies(partid)
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   709
                results = partrep['pushkey']
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   710
                assert len(results) <= 1
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   711
                msg = None
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   712
                if not results:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   713
                    msg = _('server ignored update of %s to public!\n') % node
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   714
                elif not int(results[0]['return']):
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   715
                    msg = _('updating %s to public failed!\n') % node
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   716
                if msg is not None:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   717
                    pushop.ui.warn(msg)
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   718
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   719
        else:
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23082
diff changeset
   720
            # fallback to independent pushkey command
21662
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   721
            for newremotehead in outdated:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   722
                r = pushop.remote.pushkey('phases',
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   723
                                          newremotehead.hex(),
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   724
                                          str(phases.draft),
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   725
                                          str(phases.public))
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   726
                if not r:
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   727
                    pushop.ui.warn(_('updating %s to public failed!\n')
09f19e09f1b4 push: use bundle2 to push phases when available
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21658
diff changeset
   728
                                   % newremotehead)
20441
eca9d5375606 push: move phases synchronisation function in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20440
diff changeset
   729
20438
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   730
def _localphasemove(pushop, nodes, phase=phases.public):
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   731
    """move <nodes> to <phase> in the local source repo"""
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   732
    if pushop.locallocked:
22051
e894de232f35 push: wrap local phase movement in a transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22036
diff changeset
   733
        tr = pushop.repo.transaction('push-phase-sync')
e894de232f35 push: wrap local phase movement in a transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22036
diff changeset
   734
        try:
22069
616a455b02ca phase: add a transaction argument to advanceboundary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22068
diff changeset
   735
            phases.advanceboundary(pushop.repo, tr, phase, nodes)
22051
e894de232f35 push: wrap local phase movement in a transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22036
diff changeset
   736
            tr.close()
e894de232f35 push: wrap local phase movement in a transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22036
diff changeset
   737
        finally:
e894de232f35 push: wrap local phase movement in a transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22036
diff changeset
   738
            tr.release()
20438
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   739
    else:
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   740
        # repo is not locked, do not change any phases!
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   741
        # Informs the user that phases should have been moved when
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   742
        # applicable.
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   743
        actualmoves = [n for n in nodes if phase < pushop.repo[n].phase()]
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   744
        phasestr = phases.phasenames[phase]
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   745
        if actualmoves:
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   746
            pushop.ui.status(_('cannot lock source repo, skipping '
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   747
                               'local %s phase update\n') % phasestr)
2b5ab0d11327 push: move local phase move in a normal function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20437
diff changeset
   748
20433
6af248474224 push: feed pushoperation object to _pushobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20432
diff changeset
   749
def _pushobsolete(pushop):
20434
e009e59e4566 push: drop now outdated comment
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20433
diff changeset
   750
    """utility function to push obsolete markers to a remote"""
22036
f1528ef123f4 push: use stepsdone for obsmarkers push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22035
diff changeset
   751
    if 'obsmarkers' in pushop.stepsdone:
f1528ef123f4 push: use stepsdone for obsmarkers push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22035
diff changeset
   752
        return
20435
46ede894d5a4 push: move obsolescence related message into _pushobsolescence function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20434
diff changeset
   753
    pushop.ui.debug('try to push obsolete markers to remote\n')
20433
6af248474224 push: feed pushoperation object to _pushobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20432
diff changeset
   754
    repo = pushop.repo
6af248474224 push: feed pushoperation object to _pushobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20432
diff changeset
   755
    remote = pushop.remote
22036
f1528ef123f4 push: use stepsdone for obsmarkers push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22035
diff changeset
   756
    pushop.stepsdone.add('obsmarkers')
22350
6d113cc7a31a push: only push obsmarkers relevant to the "pushed subset"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22347
diff changeset
   757
    if pushop.outobsmarkers:
20432
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   758
        rslts = []
22034
5f57bc77657c push: move the list of obsmarker to push into the push operation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22033
diff changeset
   759
        remotedata = obsolete._pushkeyescape(pushop.outobsmarkers)
20432
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   760
        for key in sorted(remotedata, reverse=True):
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   761
            # reverse sort to ensure we end with dump0
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   762
            data = remotedata[key]
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   763
            rslts.append(remote.pushkey('obsolete', key, '', data))
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   764
        if [r for r in rslts if not r]:
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   765
            msg = _('failed to push some obsolete markers!\n')
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   766
            repo.ui.warn(msg)
1b926f0bbf8a push: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20431
diff changeset
   767
20431
bebf8b8479f3 push: feed pushoperation object to _pushbookmark function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20352
diff changeset
   768
def _pushbookmark(pushop):
20352
58300f61b139 push: move bookmarks exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20351
diff changeset
   769
    """Update bookmark position on remote"""
22615
4f14303e8954 push: rename `pushop.ret` to `pushop.cgresult`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22543
diff changeset
   770
    if pushop.cgresult == 0 or 'bookmarks' in pushop.stepsdone:
22228
a3dc2d385490 pushbookmark: do not attempt to update bookmarks if the push failed (BC)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22227
diff changeset
   771
        return
22240
d092f4b68fb6 push: use stepsdone to control bookmark push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22239
diff changeset
   772
    pushop.stepsdone.add('bookmarks')
20431
bebf8b8479f3 push: feed pushoperation object to _pushbookmark function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20352
diff changeset
   773
    ui = pushop.ui
bebf8b8479f3 push: feed pushoperation object to _pushbookmark function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20352
diff changeset
   774
    remote = pushop.remote
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   775
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   776
    for b, old, new in pushop.outbookmarks:
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   777
        action = 'update'
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   778
        if not old:
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   779
            action = 'export'
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   780
        elif not new:
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   781
            action = 'delete'
22239
0688010ee38f push: move bookmark discovery with other discovery steps
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22238
diff changeset
   782
        if remote.pushkey('bookmarks', b, old, new):
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   783
            ui.status(bookmsgmap[action][0] % b)
20352
58300f61b139 push: move bookmarks exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20351
diff changeset
   784
        else:
22650
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   785
            ui.warn(bookmsgmap[action][1] % b)
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   786
            # discovery can have set the value form invalid entry
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   787
            if pushop.bkresult is not None:
36952c91e6c3 push: prepare the issue of multiple kinds of messages
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22649
diff changeset
   788
                pushop.bkresult = 1
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   789
20472
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   790
class pulloperation(object):
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   791
    """A object that represent a single pull operation
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   792
23219
61cd79ac4b99 exchange: swap "push" for "pull" in pulloperation docstring
Mike Edgar <adgar@google.com>
parents: 23218
diff changeset
   793
    It purpose is to carry pull related state and very common operation.
20472
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   794
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
   795
    A new should be created at the beginning of each pull and discarded
20472
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   796
    afterward.
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   797
    """
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   798
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   799
    def __init__(self, repo, remote, heads=None, force=False, bookmarks=()):
20596
004a1744088d exchange: fix docs for pulloperation
Siddharth Agarwal <sid0@fb.com>
parents: 20489
diff changeset
   800
        # repo we pull into
20472
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   801
        self.repo = repo
20596
004a1744088d exchange: fix docs for pulloperation
Siddharth Agarwal <sid0@fb.com>
parents: 20489
diff changeset
   802
        # repo we pull from
20473
1516daaca632 pull: move `remote` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20472
diff changeset
   803
        self.remote = remote
20474
c9bceafc61be pull: move `heads` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20473
diff changeset
   804
        # revision we try to pull (None is "all")
c9bceafc61be pull: move `heads` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20473
diff changeset
   805
        self.heads = heads
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   806
        # bookmark pulled explicitly
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   807
        self.explicitbookmarks = bookmarks
20475
b79b405583af pull: move `force` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20474
diff changeset
   808
        # do we force pull?
b79b405583af pull: move `force` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20474
diff changeset
   809
        self.force = force
20477
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   810
        # the name the pull transaction
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   811
        self._trname = 'pull\n' + util.hidepassword(remote.url())
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   812
        # hold the transaction once created
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   813
        self._tr = None
20487
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   814
        # set of common changeset between local and remote before pull
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   815
        self.common = None
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   816
        # set of pulled head
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   817
        self.rheads = None
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
   818
        # list of missing changeset to fetch remotely
20488
76e66654f74e pull: move `fetch` subset into the object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20487
diff changeset
   819
        self.fetch = None
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   820
        # remote bookmarks data
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   821
        self.remotebookmarks = None
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
   822
        # result of changegroup pulling (used as return code by pull)
20898
f295b2ac3579 pull: move return code in the pull operation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20878
diff changeset
   823
        self.cgresult = None
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
   824
        # list of step already done
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
   825
        self.stepsdone = set()
20487
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   826
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   827
    @util.propertycache
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   828
    def pulledsubset(self):
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   829
        """heads of the set of changeset target by the pull"""
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   830
        # compute target subset
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   831
        if self.heads is None:
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   832
            # We pulled every thing possible
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   833
            # sync on everything common
20878
09e7118715eb pull: prevent duplicated entry in `op.pulledsubset`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20596
diff changeset
   834
            c = set(self.common)
09e7118715eb pull: prevent duplicated entry in `op.pulledsubset`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20596
diff changeset
   835
            ret = list(self.common)
09e7118715eb pull: prevent duplicated entry in `op.pulledsubset`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20596
diff changeset
   836
            for n in self.rheads:
09e7118715eb pull: prevent duplicated entry in `op.pulledsubset`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20596
diff changeset
   837
                if n not in c:
09e7118715eb pull: prevent duplicated entry in `op.pulledsubset`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20596
diff changeset
   838
                    ret.append(n)
09e7118715eb pull: prevent duplicated entry in `op.pulledsubset`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20596
diff changeset
   839
            return ret
20487
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   840
        else:
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   841
            # We pulled a specific subset
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   842
            # sync on this subset
f715cc0b5107 pull: make pulled subset a propertycache of the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20486
diff changeset
   843
            return self.heads
20477
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   844
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   845
    def gettransaction(self):
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   846
        """get appropriate pull transaction, creating it if needed"""
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   847
        if self._tr is None:
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   848
            self._tr = self.repo.transaction(self._trname)
22972
44b16b59b80a pull: add source information to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22971
diff changeset
   849
            self._tr.hookargs['source'] = 'pull'
44b16b59b80a pull: add source information to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22971
diff changeset
   850
            self._tr.hookargs['url'] = self.remote.url()
20477
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   851
        return self._tr
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   852
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   853
    def closetransaction(self):
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   854
        """close transaction if created"""
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   855
        if self._tr is not None:
23000
90c425f80316 pull: call the `b2x-transactionclose` hook when closing the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22972
diff changeset
   856
            repo = self.repo
23203
3872d563e01a changelog: handle writepending in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23180
diff changeset
   857
            p = lambda: self._tr.writepending() and repo.root or ""
23000
90c425f80316 pull: call the `b2x-transactionclose` hook when closing the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22972
diff changeset
   858
            repo.hook('b2x-pretransactionclose', throw=True, pending=p,
90c425f80316 pull: call the `b2x-transactionclose` hook when closing the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22972
diff changeset
   859
                      **self._tr.hookargs)
23047
f10019d2ee0a hook: schedule run "b2x-transactionclose" for after lock release
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23028
diff changeset
   860
            hookargs = dict(self._tr.hookargs)
f10019d2ee0a hook: schedule run "b2x-transactionclose" for after lock release
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23028
diff changeset
   861
            def runhooks():
f10019d2ee0a hook: schedule run "b2x-transactionclose" for after lock release
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23028
diff changeset
   862
                repo.hook('b2x-transactionclose', **hookargs)
23222
6b7e60fb0b38 exchange: use the postclose API on transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23219
diff changeset
   863
            self._tr.addpostclose('b2x-hook-transactionclose',
23282
6c1351352b6c transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23222
diff changeset
   864
                                  lambda tr: repo._afterlock(runhooks))
23222
6b7e60fb0b38 exchange: use the postclose API on transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23219
diff changeset
   865
            self._tr.close()
20477
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   866
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   867
    def releasetransaction(self):
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   868
        """release transaction if created"""
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   869
        if self._tr is not None:
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   870
            self._tr.release()
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   871
22645
6e431e1635b6 pull: move bookmark movements inside the `exchange.pull`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22628
diff changeset
   872
def pull(repo, remote, heads=None, force=False, bookmarks=()):
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   873
    pullop = pulloperation(repo, remote, heads, force, bookmarks=bookmarks)
20473
1516daaca632 pull: move `remote` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20472
diff changeset
   874
    if pullop.remote.local():
1516daaca632 pull: move `remote` argument into pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20472
diff changeset
   875
        missing = set(pullop.remote.requirements) - pullop.repo.supported
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   876
        if missing:
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   877
            msg = _("required features are not"
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   878
                    " supported in the destination:"
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   879
                    " %s") % (', '.join(sorted(missing)))
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   880
            raise util.Abort(msg)
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   881
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
   882
    pullop.remotebookmarks = remote.listkeys('bookmarks')
20472
b97a453b8c27 pull: introduce a pulloperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20469
diff changeset
   883
    lock = pullop.repo.lock()
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   884
    try:
20900
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   885
        _pulldiscovery(pullop)
21256
750c7c14a637 bundle2: fix configuration name mismatch
Durham Goode <durham@fb.com>
parents: 21192
diff changeset
   886
        if (pullop.repo.ui.configbool('experimental', 'bundle2-exp', False)
21148
468cd774aa22 bundle2: require both client and server to opt in
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21146
diff changeset
   887
            and pullop.remote.capable('bundle2-exp')):
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   888
            _pullbundle2(pullop)
22653
d94f5bec9c8e pull: perform the todostep inside functions handling old way of pulling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22651
diff changeset
   889
        _pullchangeset(pullop)
d94f5bec9c8e pull: perform the todostep inside functions handling old way of pulling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22651
diff changeset
   890
        _pullphase(pullop)
22655
f48ac29c2a9e pull: retrieve bookmarks before obsmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22654
diff changeset
   891
        _pullbookmarks(pullop)
22653
d94f5bec9c8e pull: perform the todostep inside functions handling old way of pulling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22651
diff changeset
   892
        _pullobsolete(pullop)
20477
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   893
        pullop.closetransaction()
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   894
    finally:
20477
2607a21bb40b pull: move transaction logic into the pull object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   895
        pullop.releasetransaction()
20469
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   896
        lock.release()
6b4c789d618d exchange: extract pull function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20468
diff changeset
   897
22693
68439b154063 exchange: have `pull` return the pulloperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22666
diff changeset
   898
    return pullop
20476
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
   899
22936
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   900
# list of steps to perform discovery before pull
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   901
pulldiscoveryorder = []
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   902
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   903
# Mapping between step name and function
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   904
#
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   905
# This exists to help extensions wrap steps if necessary
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   906
pulldiscoverymapping = {}
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   907
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   908
def pulldiscovery(stepname):
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   909
    """decorator for function performing discovery before pull
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   910
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   911
    The function is added to the step -> function mapping and appended to the
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   912
    list of steps.  Beware that decorated function will be added in order (this
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   913
    may matter).
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   914
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   915
    You can only use this decorator for a new step, if you want to wrap a step
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   916
    from an extension, change the pulldiscovery dictionary directly."""
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   917
    def dec(func):
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   918
        assert stepname not in pulldiscoverymapping
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   919
        pulldiscoverymapping[stepname] = func
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   920
        pulldiscoveryorder.append(stepname)
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   921
        return func
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   922
    return dec
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   923
20900
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   924
def _pulldiscovery(pullop):
22936
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   925
    """Run all discovery steps"""
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   926
    for stepname in pulldiscoveryorder:
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   927
        step = pulldiscoverymapping[stepname]
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   928
        step(pullop)
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   929
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   930
@pulldiscovery('changegroup')
dae236906fb2 pull: make discovery phase extensible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22693
diff changeset
   931
def _pulldiscoverychangegroup(pullop):
20900
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   932
    """discovery phase for the pull
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   933
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   934
    Current handle changeset discovery only, will change handle all discovery
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   935
    at some point."""
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   936
    tmp = discovery.findcommonincoming(pullop.repo.unfiltered(),
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   937
                                       pullop.remote,
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   938
                                       heads=pullop.heads,
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   939
                                       force=pullop.force)
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   940
    pullop.common, pullop.fetch, pullop.rheads = tmp
cb37fb91bc5a pull: put discovery step in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20899
diff changeset
   941
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   942
def _pullbundle2(pullop):
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   943
    """pull data using bundle2
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   944
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   945
    For now, the only supported data are changegroup."""
21658
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   946
    remotecaps = bundle2.bundle2caps(pullop.remote)
21645
aed14bb165f3 bundle2: introduce a ``caps20to10`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21644
diff changeset
   947
    kwargs = {'bundlecaps': caps20to10(pullop.repo)}
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   948
    # pulling changegroup
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
   949
    pullop.stepsdone.add('changegroup')
21259
ab5040cd5749 bundle2: fix bundle2 pulling all revs on empty pulls
Durham Goode <durham@fb.com>
parents: 21258
diff changeset
   950
ab5040cd5749 bundle2: fix bundle2 pulling all revs on empty pulls
Durham Goode <durham@fb.com>
parents: 21258
diff changeset
   951
    kwargs['common'] = pullop.common
ab5040cd5749 bundle2: fix bundle2 pulling all revs on empty pulls
Durham Goode <durham@fb.com>
parents: 21258
diff changeset
   952
    kwargs['heads'] = pullop.heads or pullop.rheads
22352
dc371d1f0de1 pull: use the "cg" argument when pulling a bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22350
diff changeset
   953
    kwargs['cg'] = pullop.fetch
21658
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   954
    if 'b2x:listkeys' in remotecaps:
22656
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
   955
        kwargs['listkeys'] = ['phase', 'bookmarks']
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   956
    if not pullop.fetch:
21258
71931b789424 exchange: fix bad indentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21257
diff changeset
   957
        pullop.repo.ui.status(_("no changes found\n"))
71931b789424 exchange: fix bad indentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21257
diff changeset
   958
        pullop.cgresult = 0
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   959
    else:
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   960
        if pullop.heads is None and list(pullop.common) == [nullid]:
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   961
            pullop.repo.ui.status(_("requesting all changes\n"))
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 22937
diff changeset
   962
    if obsolete.isenabled(pullop.repo, obsolete.exchangeopt):
22354
a89add6c6b2f bundle2: pull obsmarkers relevant to the pulled set through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22353
diff changeset
   963
        remoteversions = bundle2.obsmarkersversion(remotecaps)
a89add6c6b2f bundle2: pull obsmarkers relevant to the pulled set through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22353
diff changeset
   964
        if obsolete.commonversion(remoteversions) is not None:
a89add6c6b2f bundle2: pull obsmarkers relevant to the pulled set through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22353
diff changeset
   965
            kwargs['obsmarkers'] = True
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
   966
            pullop.stepsdone.add('obsmarkers')
21159
024f38f6d5f6 bundle2: allow extensions to extend the getbundle request
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21158
diff changeset
   967
    _pullbundle2extraprepare(pullop, kwargs)
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   968
    if kwargs.keys() == ['format']:
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   969
        return # nothing to pull
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   970
    bundle = pullop.remote.getbundle('pull', **kwargs)
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   971
    try:
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   972
        op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
21618
7568f5c1c801 bundle2: move exception classes into the error module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21617
diff changeset
   973
    except error.BundleValueError, exc:
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   974
        raise util.Abort('missing support for %s' % exc)
21259
ab5040cd5749 bundle2: fix bundle2 pulling all revs on empty pulls
Durham Goode <durham@fb.com>
parents: 21258
diff changeset
   975
ab5040cd5749 bundle2: fix bundle2 pulling all revs on empty pulls
Durham Goode <durham@fb.com>
parents: 21258
diff changeset
   976
    if pullop.fetch:
22961
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   977
        changedheads = 0
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   978
        pullop.cgresult = 1
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   979
        for cg in op.records['changegroup']:
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   980
            ret = cg['return']
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   981
            # If any changegroup result is 0, return 0
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   982
            if ret == 0:
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   983
                pullop.cgresult = 0
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   984
                break
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   985
            if ret < -1:
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   986
                changedheads += ret + 1
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   987
            elif ret > 1:
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   988
                changedheads += ret - 1
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   989
        if changedheads > 0:
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   990
            pullop.cgresult = 1 + changedheads
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   991
        elif changedheads < 0:
a67ea4959ef5 bundle2: merge return values when bundle contains multiple changegroups
Mike Hommey <mh@glandium.org>
parents: 22953
diff changeset
   992
            pullop.cgresult = -1 + changedheads
20955
12f161f08d74 bundle2: allow pulling changegroups using bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20954
diff changeset
   993
21658
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   994
    # processing phases change
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   995
    for namespace, value in op.records['listkeys']:
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   996
        if namespace == 'phases':
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   997
            _pullapplyphases(pullop, value)
0696ca0a685b pull: when remote supports it, pull phase data alongside changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21657
diff changeset
   998
22656
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
   999
    # processing bookmark update
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
  1000
    for namespace, value in op.records['listkeys']:
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
  1001
        if namespace == 'bookmarks':
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
  1002
            pullop.remotebookmarks = value
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
  1003
            _pullbookmarks(pullop)
c9276945eba3 pull: retrieve bookmarks through bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22655
diff changeset
  1004
21159
024f38f6d5f6 bundle2: allow extensions to extend the getbundle request
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21158
diff changeset
  1005
def _pullbundle2extraprepare(pullop, kwargs):
024f38f6d5f6 bundle2: allow extensions to extend the getbundle request
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21158
diff changeset
  1006
    """hook function so that extensions can extend the getbundle call"""
024f38f6d5f6 bundle2: allow extensions to extend the getbundle request
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21158
diff changeset
  1007
    pass
024f38f6d5f6 bundle2: allow extensions to extend the getbundle request
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21158
diff changeset
  1008
20489
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1009
def _pullchangeset(pullop):
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1010
    """pull changeset from unbundle into the local repo"""
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1011
    # We delay the open of the transaction as late as possible so we
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1012
    # don't open transaction for nothing or you break future useful
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1013
    # rollback call
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1014
    if 'changegroup' in pullop.stepsdone:
22653
d94f5bec9c8e pull: perform the todostep inside functions handling old way of pulling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22651
diff changeset
  1015
        return
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1016
    pullop.stepsdone.add('changegroup')
20899
d62319f91cb7 pull: move the cgresult logic in _pullchangeset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20898
diff changeset
  1017
    if not pullop.fetch:
23217
2f12ac53b528 exchange: fix indentation in _pullchangeset
Mike Edgar <adgar@google.com>
parents: 23208
diff changeset
  1018
        pullop.repo.ui.status(_("no changes found\n"))
2f12ac53b528 exchange: fix indentation in _pullchangeset
Mike Edgar <adgar@google.com>
parents: 23208
diff changeset
  1019
        pullop.cgresult = 0
2f12ac53b528 exchange: fix indentation in _pullchangeset
Mike Edgar <adgar@google.com>
parents: 23208
diff changeset
  1020
        return
20489
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1021
    pullop.gettransaction()
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1022
    if pullop.heads is None and list(pullop.common) == [nullid]:
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1023
        pullop.repo.ui.status(_("requesting all changes\n"))
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1024
    elif pullop.heads is None and pullop.remote.capable('changegroupsubset'):
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1025
        # issue1320, avoid a race if remote changed after discovery
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1026
        pullop.heads = pullop.rheads
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1027
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1028
    if pullop.remote.capable('getbundle'):
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1029
        # TODO: get bundlecaps from remote
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1030
        cg = pullop.remote.getbundle('pull', common=pullop.common,
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1031
                                     heads=pullop.heads or pullop.rheads)
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1032
    elif pullop.heads is None:
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1033
        cg = pullop.remote.changegroup(pullop.fetch, 'pull')
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1034
    elif not pullop.remote.capable('changegroupsubset'):
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1035
        raise util.Abort(_("partial pull cannot be done because "
21554
7bcf4adadd2d exchange: fix indentation level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21259
diff changeset
  1036
                           "other repository doesn't support "
7bcf4adadd2d exchange: fix indentation level
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21259
diff changeset
  1037
                           "changegroupsubset."))
20489
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1038
    else:
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1039
        cg = pullop.remote.changegroupsubset(pullop.fetch, pullop.heads, 'pull')
20933
d3775db748a0 localrepo: move the addchangegroup method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20928
diff changeset
  1040
    pullop.cgresult = changegroup.addchangegroup(pullop.repo, cg, 'pull',
20899
d62319f91cb7 pull: move the cgresult logic in _pullchangeset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20898
diff changeset
  1041
                                                 pullop.remote.url())
20489
7b5ec1c7e8e2 pull: move changeset pulling in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20488
diff changeset
  1042
20486
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1043
def _pullphase(pullop):
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1044
    # Get remote phases data from remote
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1045
    if 'phases' in pullop.stepsdone:
22653
d94f5bec9c8e pull: perform the todostep inside functions handling old way of pulling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22651
diff changeset
  1046
        return
21654
ddf9a00c1239 pull: split remote phases retrieval from actual application
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21645
diff changeset
  1047
    remotephases = pullop.remote.listkeys('phases')
ddf9a00c1239 pull: split remote phases retrieval from actual application
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21645
diff changeset
  1048
    _pullapplyphases(pullop, remotephases)
ddf9a00c1239 pull: split remote phases retrieval from actual application
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21645
diff changeset
  1049
ddf9a00c1239 pull: split remote phases retrieval from actual application
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21645
diff changeset
  1050
def _pullapplyphases(pullop, remotephases):
ddf9a00c1239 pull: split remote phases retrieval from actual application
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21645
diff changeset
  1051
    """apply phase movement from observed remote state"""
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1052
    if 'phases' in pullop.stepsdone:
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1053
        return
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1054
    pullop.stepsdone.add('phases')
20486
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1055
    publishing = bool(remotephases.get('publishing', False))
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1056
    if remotephases and not publishing:
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1057
        # remote is new and unpublishing
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1058
        pheads, _dr = phases.analyzeremotephases(pullop.repo,
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1059
                                                 pullop.pulledsubset,
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1060
                                                 remotephases)
22068
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1061
        dheads = pullop.pulledsubset
20486
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1062
    else:
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1063
        # Remote is old or publishing all common changesets
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1064
        # should be seen as public
22068
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1065
        pheads = pullop.pulledsubset
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1066
        dheads = []
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1067
    unfi = pullop.repo.unfiltered()
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1068
    phase = unfi._phasecache.phase
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1069
    rev = unfi.changelog.nodemap.get
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1070
    public = phases.public
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1071
    draft = phases.draft
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1072
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1073
    # exclude changesets already public locally and update the others
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1074
    pheads = [pn for pn in pheads if phase(unfi, rev(pn)) > public]
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1075
    if pheads:
22069
616a455b02ca phase: add a transaction argument to advanceboundary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22068
diff changeset
  1076
        tr = pullop.gettransaction()
616a455b02ca phase: add a transaction argument to advanceboundary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22068
diff changeset
  1077
        phases.advanceboundary(pullop.repo, tr, public, pheads)
22068
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1078
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1079
    # exclude changesets already draft locally and update the others
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1080
    dheads = [pn for pn in dheads if phase(unfi, rev(pn)) > draft]
d34058dd3246 pull: pre-filter remote phases before moving local ones
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
  1081
    if dheads:
22069
616a455b02ca phase: add a transaction argument to advanceboundary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22068
diff changeset
  1082
        tr = pullop.gettransaction()
616a455b02ca phase: add a transaction argument to advanceboundary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22068
diff changeset
  1083
        phases.advanceboundary(pullop.repo, tr, draft, dheads)
20486
0c469df6e914 pull: move phases synchronisation in its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20485
diff changeset
  1084
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1085
def _pullbookmarks(pullop):
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1086
    """process the remote bookmark information to update the local one"""
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1087
    if 'bookmarks' in pullop.stepsdone:
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1088
        return
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1089
    pullop.stepsdone.add('bookmarks')
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1090
    repo = pullop.repo
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1091
    remotebookmarks = pullop.remotebookmarks
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1092
    bookmod.updatefromremote(repo.ui, repo, remotebookmarks,
22658
a8f0d8e4c80a pull: gather explicit bookmark pulls with bookmark updates
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22656
diff changeset
  1093
                             pullop.remote.url(),
22666
0f8120c1ecf5 pull: perform bookmark updates in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22658
diff changeset
  1094
                             pullop.gettransaction,
22658
a8f0d8e4c80a pull: gather explicit bookmark pulls with bookmark updates
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22656
diff changeset
  1095
                             explicit=pullop.explicitbookmarks)
22654
02e0a574bcd3 pull: move bookmark pulling into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22653
diff changeset
  1096
20478
80628d4069be push: feed pulloperation object to _pullobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20477
diff changeset
  1097
def _pullobsolete(pullop):
20476
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1098
    """utility function to pull obsolete markers from a remote
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1099
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1100
    The `gettransaction` is function that return the pull transaction, creating
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1101
    one if necessary. We return the transaction to inform the calling code that
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1102
    a new transaction have been created (when applicable).
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1103
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1104
    Exists mostly to allow overriding for experimentation purpose"""
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1105
    if 'obsmarkers' in pullop.stepsdone:
22653
d94f5bec9c8e pull: perform the todostep inside functions handling old way of pulling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22651
diff changeset
  1106
        return
22937
92bf9abc4deb pull: use `stepsdone` instead of `todosteps`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22936
diff changeset
  1107
    pullop.stepsdone.add('obsmarkers')
20476
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1108
    tr = None
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 22937
diff changeset
  1109
    if obsolete.isenabled(pullop.repo, obsolete.exchangeopt):
20478
80628d4069be push: feed pulloperation object to _pullobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20477
diff changeset
  1110
        pullop.repo.ui.debug('fetching remote obsolete markers\n')
80628d4069be push: feed pulloperation object to _pullobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20477
diff changeset
  1111
        remoteobs = pullop.remote.listkeys('obsolete')
20476
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1112
        if 'dump0' in remoteobs:
20478
80628d4069be push: feed pulloperation object to _pullobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20477
diff changeset
  1113
            tr = pullop.gettransaction()
20476
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1114
            for key in sorted(remoteobs, reverse=True):
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1115
                if key.startswith('dump'):
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1116
                    data = base85.b85decode(remoteobs[key])
20478
80628d4069be push: feed pulloperation object to _pullobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20477
diff changeset
  1117
                    pullop.repo.obsstore.mergemarkers(tr, data)
80628d4069be push: feed pulloperation object to _pullobsolete function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20477
diff changeset
  1118
            pullop.repo.invalidatevolatilesets()
20476
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1119
    return tr
1180c6ec5695 pull: move obsolescence marker exchange in the exchange module
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20475
diff changeset
  1120
21645
aed14bb165f3 bundle2: introduce a ``caps20to10`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21644
diff changeset
  1121
def caps20to10(repo):
aed14bb165f3 bundle2: introduce a ``caps20to10`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21644
diff changeset
  1122
    """return a set with appropriate options to use bundle20 during getbundle"""
23009
90f86ad3d4ff bundle2: change header size and make them signed (new format)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23000
diff changeset
  1123
    caps = set(['HG2Y'])
22342
262c5cc126c1 bundle2: introduce a `getrepocaps` to retrieve the bundle2 caps of a repo
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22341
diff changeset
  1124
    capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
21645
aed14bb165f3 bundle2: introduce a ``caps20to10`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21644
diff changeset
  1125
    caps.add('bundle2=' + urllib.quote(capsblob))
aed14bb165f3 bundle2: introduce a ``caps20to10`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21644
diff changeset
  1126
    return caps
aed14bb165f3 bundle2: introduce a ``caps20to10`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21644
diff changeset
  1127
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1128
# List of names of steps to perform for a bundle2 for getbundle, order matters.
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1129
getbundle2partsorder = []
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1130
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1131
# Mapping between step name and function
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1132
#
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1133
# This exists to help extensions wrap steps if necessary
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1134
getbundle2partsmapping = {}
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1135
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1136
def getbundle2partsgenerator(stepname):
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1137
    """decorator for function generating bundle2 part for getbundle
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1138
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1139
    The function is added to the step -> function mapping and appended to the
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1140
    list of steps.  Beware that decorated functions will be added in order
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1141
    (this may matter).
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1142
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1143
    You can only use this decorator for new steps, if you want to wrap a step
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1144
    from an extension, attack the getbundle2partsmapping dictionary directly."""
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1145
    def dec(func):
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1146
        assert stepname not in getbundle2partsmapping
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1147
        getbundle2partsmapping[stepname] = func
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1148
        getbundle2partsorder.append(stepname)
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1149
        return func
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1150
    return dec
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1151
21157
60ad2ea5b106 getbundle: pass arbitrary arguments all along the call chain
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21156
diff changeset
  1152
def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
60ad2ea5b106 getbundle: pass arbitrary arguments all along the call chain
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21156
diff changeset
  1153
              **kwargs):
20954
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1154
    """return a full bundle (with potentially multiple kind of parts)
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1155
23009
90f86ad3d4ff bundle2: change header size and make them signed (new format)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23000
diff changeset
  1156
    Could be a bundle HG10 or a bundle HG2Y depending on bundlecaps
20954
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1157
    passed. For now, the bundle can contain only changegroup, but this will
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1158
    changes when more part type will be available for bundle2.
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1159
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22354
diff changeset
  1160
    This is different from changegroup.getchangegroup that only returns an HG10
20954
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1161
    changegroup bundle. They may eventually get reunited in the future when we
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1162
    have a clearer idea of the API we what to query different data.
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1163
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1164
    The implementation is at a very early stage and will get massive rework
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1165
    when the API of bundle is refined.
dba91f8060eb bundle2: add an exchange.getbundle function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1166
    """
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1167
    # bundle10 case
23009
90f86ad3d4ff bundle2: change header size and make them signed (new format)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23000
diff changeset
  1168
    if bundlecaps is None or 'HG2Y' not in bundlecaps:
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1169
        if bundlecaps and not kwargs.get('cg', True):
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1170
            raise ValueError(_('request for bundle10 must include changegroup'))
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1171
21656
36200dc6b3bd getbundle: raise error if extra arguments are provided for bundle10
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21654
diff changeset
  1172
        if kwargs:
36200dc6b3bd getbundle: raise error if extra arguments are provided for bundle10
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21654
diff changeset
  1173
            raise ValueError(_('unsupported getbundle arguments: %s')
36200dc6b3bd getbundle: raise error if extra arguments are provided for bundle10
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21654
diff changeset
  1174
                             % ', '.join(sorted(kwargs.keys())))
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1175
        return changegroup.getchangegroup(repo, source, heads=heads,
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1176
                                          common=common, bundlecaps=bundlecaps)
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1177
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1178
    # bundle20 case
21143
5bb5d4ba14e5 bundle2: transmit capabilities to getbundle during pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21142
diff changeset
  1179
    b2caps = {}
5bb5d4ba14e5 bundle2: transmit capabilities to getbundle during pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21142
diff changeset
  1180
    for bcaps in bundlecaps:
5bb5d4ba14e5 bundle2: transmit capabilities to getbundle during pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21142
diff changeset
  1181
        if bcaps.startswith('bundle2='):
5bb5d4ba14e5 bundle2: transmit capabilities to getbundle during pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21142
diff changeset
  1182
            blob = urllib.unquote(bcaps[len('bundle2='):])
5bb5d4ba14e5 bundle2: transmit capabilities to getbundle during pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21142
diff changeset
  1183
            b2caps.update(bundle2.decodecaps(blob))
5bb5d4ba14e5 bundle2: transmit capabilities to getbundle during pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21142
diff changeset
  1184
    bundler = bundle2.bundle20(repo.ui, b2caps)
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1185
23218
0e78ea8e592a exchange: prepare kwargs for bundle2 part generation exactly once
Mike Edgar <adgar@google.com>
parents: 23217
diff changeset
  1186
    kwargs['heads'] = heads
0e78ea8e592a exchange: prepare kwargs for bundle2 part generation exactly once
Mike Edgar <adgar@google.com>
parents: 23217
diff changeset
  1187
    kwargs['common'] = common
0e78ea8e592a exchange: prepare kwargs for bundle2 part generation exactly once
Mike Edgar <adgar@google.com>
parents: 23217
diff changeset
  1188
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1189
    for name in getbundle2partsorder:
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1190
        func = getbundle2partsmapping[name]
22543
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1191
        func(bundler, repo, source, bundlecaps=bundlecaps, b2caps=b2caps,
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1192
             **kwargs)
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1193
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1194
    return util.chunkbuffer(bundler.getchunks())
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1195
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1196
@getbundle2partsgenerator('changegroup')
22543
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1197
def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1198
                              b2caps=None, heads=None, common=None, **kwargs):
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1199
    """add a changegroup part to the requested bundle"""
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1200
    cg = None
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1201
    if kwargs.get('cg', True):
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1202
        # build changegroup bundle here.
23179
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1203
        version = None
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1204
        cgversions = b2caps.get('b2x:changegroup')
23208
f606e07fa148 bundle2: handle empty 'b2x:changegroup' value in push and pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23203
diff changeset
  1205
        if not cgversions:  # 3.1 and 3.2 ship with an empty value
23179
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1206
            cg = changegroup.getchangegroupraw(repo, source, heads=heads,
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1207
                                               common=common,
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1208
                                               bundlecaps=bundlecaps)
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1209
        else:
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1210
            cgversions = [v for v in cgversions if v in changegroup.packermap]
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1211
            if not cgversions:
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1212
                raise ValueError(_('no common changegroup version'))
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1213
            version = max(cgversions)
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1214
            cg = changegroup.getchangegroupraw(repo, source, heads=heads,
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1215
                                               common=common,
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1216
                                               bundlecaps=bundlecaps,
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1217
                                               version=version)
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1218
21259
ab5040cd5749 bundle2: fix bundle2 pulling all revs on empty pulls
Durham Goode <durham@fb.com>
parents: 21258
diff changeset
  1219
    if cg:
23179
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1220
        part = bundler.newpart('b2x:changegroup', data=cg)
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1221
        if version is not None:
6bb9533fa8fa getbundle: send highest changegroup format supported by both side
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23177
diff changeset
  1222
            part.addparam('version', version)
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1223
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1224
@getbundle2partsgenerator('listkeys')
22543
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1225
def _getbundlelistkeysparts(bundler, repo, source, bundlecaps=None,
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1226
                            b2caps=None, **kwargs):
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1227
    """add parts containing listkeys namespaces to the requested bundle"""
21657
0ff44e06275d getbundle: support of listkeys argument when bundle2 is used
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21656
diff changeset
  1228
    listkeys = kwargs.get('listkeys', ())
0ff44e06275d getbundle: support of listkeys argument when bundle2 is used
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21656
diff changeset
  1229
    for namespace in listkeys:
0ff44e06275d getbundle: support of listkeys argument when bundle2 is used
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21656
diff changeset
  1230
        part = bundler.newpart('b2x:listkeys')
0ff44e06275d getbundle: support of listkeys argument when bundle2 is used
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21656
diff changeset
  1231
        part.addparam('namespace', namespace)
0ff44e06275d getbundle: support of listkeys argument when bundle2 is used
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21656
diff changeset
  1232
        keys = repo.listkeys(namespace).items()
0ff44e06275d getbundle: support of listkeys argument when bundle2 is used
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21656
diff changeset
  1233
        part.data = pushkey.encodekeys(keys)
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1234
22542
6b180a0c703e bundle2: separate bundle10 and bundle2 cases in getbundle()
Mike Hommey <mh@glandium.org>
parents: 22541
diff changeset
  1235
@getbundle2partsgenerator('obsmarkers')
22543
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1236
def _getbundleobsmarkerpart(bundler, repo, source, bundlecaps=None,
6a669d5a62b8 bundle2: remove heads and common arguments to getbundle parts generators
Mike Hommey <mh@glandium.org>
parents: 22542
diff changeset
  1237
                            b2caps=None, heads=None, **kwargs):
22541
4e1a80c022a4 bundle2: pass b2caps down to functions adding bundle2 parts for getbundle
Mike Hommey <mh@glandium.org>
parents: 22390
diff changeset
  1238
    """add an obsolescence markers part to the requested bundle"""
22353
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1239
    if kwargs.get('obsmarkers', False):
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1240
        if heads is None:
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1241
            heads = repo.heads()
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1242
        subset = [c.node() for c in repo.set('::%ln', heads)]
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1243
        markers = repo.obsstore.relevantmarkers(subset)
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1244
        buildobsmarkerspart(bundler, markers)
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22352
diff changeset
  1245
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1246
def check_heads(repo, their_heads, context):
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1247
    """check if the heads of a repo have been modified
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1248
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1249
    Used by peer for unbundling.
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1250
    """
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1251
    heads = repo.heads()
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1252
    heads_hash = util.sha1(''.join(sorted(heads))).digest()
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1253
    if not (their_heads == ['force'] or their_heads == heads or
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1254
            their_heads == ['hashed', heads_hash]):
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1255
        # someone else committed/pushed/unbundled while we
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20956
diff changeset
  1256
        # were transferring data
21184
28d76afa1568 bundle2: fix raising errors during heads checking
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21182
diff changeset
  1257
        raise error.PushRaced('repository changed while %s - '
28d76afa1568 bundle2: fix raising errors during heads checking
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21182
diff changeset
  1258
                              'please try again' % context)
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1259
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1260
def unbundle(repo, cg, heads, source, url):
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1261
    """Apply a bundle to a repo.
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1262
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1263
    this function makes sure the repo is locked during the application and have
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21012
diff changeset
  1264
    mechanism to check that no push race occurred between the creation of the
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1265
    bundle and its application.
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1266
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1267
    If the push was raced as PushRaced exception is raised."""
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1268
    r = 0
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1269
    # need a transaction when processing a bundle2 stream
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1270
    tr = None
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1271
    lock = repo.lock()
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1272
    try:
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1273
        check_heads(repo, heads, 'uploading changes')
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1274
        # push can proceed
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1275
        if util.safehasattr(cg, 'params'):
21187
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1276
            try:
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1277
                tr = repo.transaction('unbundle')
22971
3fe571c74b27 changegroup: store source and url in the `hookargs` dict
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22961
diff changeset
  1278
                tr.hookargs['source'] = source
3fe571c74b27 changegroup: store source and url in the `hookargs` dict
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22961
diff changeset
  1279
                tr.hookargs['url'] = url
21187
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1280
                tr.hookargs['bundle2-exp'] = '1'
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1281
                r = bundle2.processbundle(repo, cg, lambda: tr).reply
23203
3872d563e01a changelog: handle writepending in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23180
diff changeset
  1282
                p = lambda: tr.writepending() and repo.root or ""
22971
3fe571c74b27 changegroup: store source and url in the `hookargs` dict
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22961
diff changeset
  1283
                repo.hook('b2x-pretransactionclose', throw=True, pending=p,
3fe571c74b27 changegroup: store source and url in the `hookargs` dict
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22961
diff changeset
  1284
                          **tr.hookargs)
23047
f10019d2ee0a hook: schedule run "b2x-transactionclose" for after lock release
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23028
diff changeset
  1285
                hookargs = dict(tr.hookargs)
f10019d2ee0a hook: schedule run "b2x-transactionclose" for after lock release
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23028
diff changeset
  1286
                def runhooks():
f10019d2ee0a hook: schedule run "b2x-transactionclose" for after lock release
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23028
diff changeset
  1287
                    repo.hook('b2x-transactionclose', **hookargs)
23222
6b7e60fb0b38 exchange: use the postclose API on transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23219
diff changeset
  1288
                tr.addpostclose('b2x-hook-transactionclose',
23282
6c1351352b6c transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23222
diff changeset
  1289
                                lambda tr: repo._afterlock(runhooks))
23222
6b7e60fb0b38 exchange: use the postclose API on transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23219
diff changeset
  1290
                tr.close()
21187
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1291
            except Exception, exc:
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1292
                exc.duringunbundle2 = True
bcfd44abad93 bundle2: gracefully handle hook abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21184
diff changeset
  1293
                raise
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1294
        else:
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1295
            r = changegroup.addchangegroup(repo, cg, source, url)
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1296
    finally:
21061
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1297
        if tr is not None:
62d35f251c60 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21043
diff changeset
  1298
            tr.release()
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1299
        lock.release()
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
  1300
    return r