annotate mercurial/exchange.py @ 20350:8c85d968ee65

push: move `revs` argument into the push object One more step toward a more modular push function.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Thu, 30 Jan 2014 17:04:23 -0800
parents 89f90457979e
children c05ad450df23
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1 # exchange.py - utily to exchange data between repo.
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 _
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
9 from node import hex
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
10 import errno
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
11 import util, scmutil, changegroup
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
12 import discovery, phases, obsolete, bookmarks
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
13
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
14
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
15 class pushoperation(object):
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
16 """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
17
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
18 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
19
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
20 A new should be created at the begining of each push and discarded
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
21 afterward.
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
22 """
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
23
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
24 def __init__(self, repo, remote, force=False, revs=None):
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
25 # repo we push from
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
26 self.repo = repo
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
27 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
28 # 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
29 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
30 # force option provided
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
31 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
32 # 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
33 self.revs = revs
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
34
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
35 def push(repo, remote, force=False, revs=None, newbranch=False):
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
36 '''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
37 repository to remote. Return an integer:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
38 - None means nothing to push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
39 - 0 means HTTP error
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
40 - 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
41 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
42 - other values as described by addchangegroup()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
43 '''
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
44 pushop = pushoperation(repo, remote, force, revs)
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
45 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
46 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
47 - pushop.remote.local().supported)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
48 if missing:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
49 msg = _("required features are not"
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
50 " supported in the destination:"
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
51 " %s") % (', '.join(sorted(missing)))
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
52 raise util.Abort(msg)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
53
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
54 # 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
55 #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
56 # 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
57 # repo (local filesystem, old ssh servers).
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
58 #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
59 # 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
60 # servers, http servers).
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
61
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
62 if not pushop.remote.canpush():
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
63 raise util.Abort(_("destination does not support push"))
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
64 unfi = pushop.repo.unfiltered()
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
65 def localphasemove(nodes, phase=phases.public):
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
66 """move <nodes> to <phase> in the local source repo"""
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
67 if locallock is not None:
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
68 phases.advanceboundary(pushop.repo, phase, nodes)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
69 else:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
70 # repo is not locked, do not change any phases!
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
71 # Informs the user that phases should have been moved when
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
72 # applicable.
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
73 actualmoves = [n for n in nodes if phase < pushop.repo[n].phase()]
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
74 phasestr = phases.phasenames[phase]
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
75 if actualmoves:
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
76 pushop.ui.status(_('cannot lock source repo, skipping '
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
77 'local %s phase update\n') % phasestr)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
78 # 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
79 locallock = None
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
80 try:
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
81 locallock = pushop.repo.lock()
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
82 except IOError, err:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
83 if err.errno != errno.EACCES:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
84 raise
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
85 # source repo cannot be locked.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
86 # 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
87 # synchronisation.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
88 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
89 pushop.ui.debug(msg)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
90 try:
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
91 pushop.repo.checkpush(pushop.force, pushop.revs)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
92 lock = None
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
93 unbundle = pushop.remote.capable('unbundle')
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
94 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
95 lock = pushop.remote.lock()
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
96 try:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
97 # discovery
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
98 fci = discovery.findcommonincoming
20349
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
99 commoninc = fci(unfi, pushop.remote, force=pushop.force)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
100 common, inc, remoteheads = commoninc
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
101 fco = discovery.findcommonoutgoing
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
102 outgoing = fco(unfi, pushop.remote, onlyheads=pushop.revs,
20349
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
103 commoninc=commoninc, force=pushop.force)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
104
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
105
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
106 if not outgoing.missing:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
107 # nothing to push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
108 scmutil.nochangesfound(unfi.ui, unfi, outgoing.excluded)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
109 ret = None
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
110 else:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
111 # something to push
20349
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
112 if not pushop.force:
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
113 # if repo.obsstore == False --> no obsolete
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
114 # then, save the iteration
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
115 if unfi.obsstore:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
116 # this message are here for 80 char limit reason
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
117 mso = _("push includes obsolete changeset: %s!")
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
118 mst = "push includes %s changeset: %s!"
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
119 # plain versions for i18n tool to detect them
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
120 _("push includes unstable changeset: %s!")
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
121 _("push includes bumped changeset: %s!")
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
122 _("push includes divergent changeset: %s!")
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
123 # If we are to push if there is at least one
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
124 # obsolete or unstable changeset in missing, at
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
125 # least one of the missinghead will be obsolete or
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
126 # unstable. So checking heads only is ok
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
127 for node in outgoing.missingheads:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
128 ctx = unfi[node]
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
129 if ctx.obsolete():
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
130 raise util.Abort(mso % ctx)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
131 elif ctx.troubled():
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
132 raise util.Abort(_(mst)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
133 % (ctx.troubles()[0],
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
134 ctx))
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
135 newbm = pushop.ui.configlist('bookmarks', 'pushing')
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
136 discovery.checkheads(unfi, pushop.remote, outgoing,
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
137 remoteheads, newbranch,
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
138 bool(inc), newbm)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
139
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
140 # TODO: get bundlecaps from remote
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
141 bundlecaps = None
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
142 # create a changegroup from local
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
143 if pushop.revs is None and not (outgoing.excluded
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
144 or pushop.repo.changelog.filteredrevs):
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
145 # push everything,
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
146 # use the fast path, no race possible on push
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
147 bundler = changegroup.bundle10(pushop.repo, bundlecaps)
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
148 cg = pushop.repo._changegroupsubset(outgoing,
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
149 bundler,
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
150 'push',
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
151 fastpath=True)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
152 else:
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
153 cg = pushop.repo.getlocalbundle('push', outgoing,
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
154 bundlecaps)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
155
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
156 # apply changegroup to remote
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
157 if unbundle:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
158 # local repo finds heads on server, finds out what
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
159 # revs it must push. once revs transferred, if server
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
160 # finds it has different heads (someone else won
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
161 # commit/push race), server aborts.
20349
89f90457979e push: move `force` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20348
diff changeset
162 if pushop.force:
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
163 remoteheads = ['force']
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
164 # ssh: return remote's addchangegroup()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
165 # http: return remote's addchangegroup() or 0 for error
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
166 ret = pushop.remote.unbundle(cg, remoteheads, 'push')
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
167 else:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
168 # we return an integer indicating remote head count
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
169 # change
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
170 ret = pushop.remote.addchangegroup(cg, 'push',
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
171 pushop.repo.url())
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
172
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
173 if ret:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
174 # push succeed, synchronize target of the push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
175 cheads = outgoing.missingheads
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
176 elif pushop.revs is None:
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
177 # All out push fails. synchronize all common
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
178 cheads = outgoing.commonheads
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
179 else:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
180 # I want cheads = heads(::missingheads and ::commonheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
181 # (missingheads is revs with secret changeset filtered out)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
182 #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
183 # This can be expressed as:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
184 # cheads = ( (missingheads and ::commonheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
185 # + (commonheads and ::missingheads))"
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 #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
188 # while trying to push we already computed the following:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
189 # common = (::commonheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
190 # missing = ((commonheads::missingheads) - commonheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
191 #
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
192 # We can pick:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
193 # * missingheads part of common (::commonheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
194 common = set(outgoing.common)
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
195 nm = pushop.repo.changelog.nodemap
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
196 cheads = [node for node in pushop.revs if nm[node] in common]
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
197 # and
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
198 # * commonheads parents on missing
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
199 revset = unfi.set('%ln and parents(roots(%ln))',
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
200 outgoing.commonheads,
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
201 outgoing.missing)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
202 cheads.extend(c.node() for c in revset)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
203 # even when we don't push, exchanging phase data is useful
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
204 remotephases = pushop.remote.listkeys('phases')
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
205 if (pushop.ui.configbool('ui', '_usedassubrepo', False)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
206 and remotephases # server supports phases
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
207 and ret is None # nothing was pushed
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
208 and remotephases.get('publishing', False)):
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
209 # When:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
210 # - this is a subrepo push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
211 # - and remote support phase
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
212 # - and no changeset was pushed
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
213 # - and remote is publishing
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
214 # We may be in issue 3871 case!
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
215 # We drop the possible phase synchronisation done by
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
216 # courtesy to publish changesets possibly locally draft
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
217 # on the remote.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
218 remotephases = {'publishing': 'True'}
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
219 if not remotephases: # old server or public only repo
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
220 localphasemove(cheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
221 # don't push any phase data as there is nothing to push
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
222 else:
20346
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
223 ana = phases.analyzeremotephases(pushop.repo, cheads,
42df1fe32552 push: introduce a pushoperation object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20345
diff changeset
224 remotephases)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
225 pheads, droots = ana
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
226 ### Apply remote phase on local
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
227 if remotephases.get('publishing', False):
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
228 localphasemove(cheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
229 else: # publish = False
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
230 localphasemove(pheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
231 localphasemove(cheads, phases.draft)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
232 ### Apply local phase on remote
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
233
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
234 # Get the list of all revs draft on remote by public here.
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
235 # XXX Beware that revset break if droots is not strictly
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
236 # XXX root we may want to ensure it is but it is costly
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
237 outdated = unfi.set('heads((%ln::%ln) and public())',
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
238 droots, cheads)
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
239 for newremotehead in outdated:
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
240 r = pushop.remote.pushkey('phases',
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
241 newremotehead.hex(),
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
242 str(phases.draft),
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
243 str(phases.public))
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
244 if not r:
20347
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
245 pushop.ui.warn(_('updating %s to public failed!\n')
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
246 % newremotehead)
3ec5f833348e push: ease access to current ui object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20346
diff changeset
247 pushop.ui.debug('try to push obsolete markers to remote\n')
20348
d64c904db55a push: move `remote` argument in the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20347
diff changeset
248 obsolete.syncpush(pushop.repo, pushop.remote)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
249 finally:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
250 if lock is not None:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
251 lock.release()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
252 finally:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
253 if locallock is not None:
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
254 locallock.release()
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
255
20350
8c85d968ee65 push: move `revs` argument into the push object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20349
diff changeset
256 bookmarks.updateremote(pushop.ui, unfi, pushop.remote, pushop.revs)
20345
8567b4ea76ac exchange: extract push function from localrepo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
257 return ret