Show More
@@ -149,39 +149,24 def findcommonoutgoing(repo, other, only | |||||
149 |
|
149 | |||
150 | return og |
|
150 | return og | |
151 |
|
151 | |||
152 | def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False): |
|
152 | def _branchmapsummary(repo, remote, outgoing): | |
153 | """Check that a push won't add any outgoing head |
|
153 | """compute a summary of branch and heads status before and after push | |
154 |
|
154 | |||
155 | raise Abort error and display ui message as needed. |
|
155 | - oldmap: {'branch': [heads]} mapping for remote | |
|
156 | - newmap: {'branch': [heads]} mapping for local | |||
|
157 | - unsynced: set of branch that have unsynced remote changes | |||
|
158 | - branches: set of all common branch pushed | |||
|
159 | - newbranches: list of plain new pushed branch | |||
156 | """ |
|
160 | """ | |
157 | if remoteheads == [nullid]: |
|
|||
158 | # remote is empty, nothing to check. |
|
|||
159 | return |
|
|||
160 |
|
||||
161 | cl = repo.changelog |
|
161 | cl = repo.changelog | |
162 | if remote.capable('branchmap'): |
|
|||
163 | # Check for each named branch if we're creating new remote heads. |
|
|||
164 | # To be a remote head after push, node must be either: |
|
|||
165 | # - unknown locally |
|
|||
166 | # - a local outgoing head descended from update |
|
|||
167 | # - a remote head that's known locally and not |
|
|||
168 | # ancestral to an outgoing head |
|
|||
169 |
|
162 | |||
170 |
|
|
163 | # A. Create set of branches involved in the push. | |
171 |
|
|
164 | branches = set(repo[n].branch() for n in outgoing.missing) | |
172 |
|
||||
173 | # 2. Check for new branches on the remote. |
|
|||
174 |
|
|
165 | remotemap = remote.branchmap() | |
175 |
|
|
166 | newbranches = branches - set(remotemap) | |
176 | if newbranches and not newbranch: # new branch requires --new-branch |
|
|||
177 | branchnames = ', '.join(sorted(newbranches)) |
|
|||
178 | raise util.Abort(_("push creates new remote branches: %s!") |
|
|||
179 | % branchnames, |
|
|||
180 | hint=_("use 'hg push --new-branch' to create" |
|
|||
181 | " new remote branches")) |
|
|||
182 |
|
|
167 | branches.difference_update(newbranches) | |
183 |
|
168 | |||
184 |
|
|
169 | # B. Construct the initial oldmap and newmap dicts. | |
185 |
|
|
170 | # They contain information about the remote heads before and | |
186 |
|
|
171 | # after the push, respectively. | |
187 |
|
|
172 | # Heads not found locally are not included in either dict, | |
@@ -192,18 +177,23 def checkheads(repo, remote, outgoing, r | |||||
192 |
|
|
177 | unsynced = set() | |
193 |
|
|
178 | for branch in branches: | |
194 |
|
|
179 | remotebrheads = remotemap[branch] | |
|
180 | ||||
195 |
|
|
181 | prunedbrheads = [h for h in remotebrheads if h in cl.nodemap] | |
196 |
|
|
182 | oldmap[branch] = prunedbrheads | |
197 |
|
|
183 | newmap[branch] = list(prunedbrheads) | |
198 |
|
|
184 | if len(remotebrheads) > len(prunedbrheads): | |
199 |
|
|
185 | unsynced.add(branch) | |
200 |
|
186 | |||
201 |
|
|
187 | # C. Update newmap with outgoing changes. | |
202 |
|
|
188 | # This will possibly add new heads and remove existing ones. | |
203 |
|
|
189 | ctxgen = (repo[n] for n in outgoing.missing) | |
204 |
|
|
190 | repo._updatebranchcache(newmap, ctxgen) | |
|
191 | return oldmap, newmap, unsynced, branches, newbranches | |||
205 |
|
192 | |||
206 | else: |
|
193 | def _oldbranchmapsummary(repo, remoteheads, outgoing, inc=False): | |
|
194 | """Compute branchmapsummary for repo without branchmap support""" | |||
|
195 | ||||
|
196 | cl = repo.changelog | |||
207 |
|
|
197 | # 1-4b. old servers: Check for new topological heads. | |
208 |
|
|
198 | # Construct {old,new}map with branch = None (topological branch). | |
209 |
|
|
199 | # (code based on _updatebranchcache) | |
@@ -218,8 +208,37 def checkheads(repo, remote, outgoing, r | |||||
218 |
|
|
208 | newmap = {None: list(c.node() for c in r)} | |
219 |
|
|
209 | oldmap = {None: oldheads} | |
220 |
|
|
210 | unsynced = inc and branches or set() | |
|
211 | return oldmap, newmap, unsynced, branches, set() | |||
221 |
|
212 | |||
222 | # 5. Check for new heads. |
|
213 | def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False): | |
|
214 | """Check that a push won't add any outgoing head | |||
|
215 | ||||
|
216 | raise Abort error and display ui message as needed. | |||
|
217 | """ | |||
|
218 | # Check for each named branch if we're creating new remote heads. | |||
|
219 | # To be a remote head after push, node must be either: | |||
|
220 | # - unknown locally | |||
|
221 | # - a local outgoing head descended from update | |||
|
222 | # - a remote head that's known locally and not | |||
|
223 | # ancestral to an outgoing head | |||
|
224 | if remoteheads == [nullid]: | |||
|
225 | # remote is empty, nothing to check. | |||
|
226 | return | |||
|
227 | ||||
|
228 | if remote.capable('branchmap'): | |||
|
229 | bms = _branchmapsummary(repo, remote, outgoing) | |||
|
230 | else: | |||
|
231 | bms = _oldbranchmapsummary(repo, remoteheads, outgoing, inc) | |||
|
232 | oldmap, newmap, unsynced, branches, newbranches = bms | |||
|
233 | # 1. Check for new branches on the remote. | |||
|
234 | if newbranches and not newbranch: # new branch requires --new-branch | |||
|
235 | branchnames = ', '.join(sorted(newbranches)) | |||
|
236 | raise util.Abort(_("push creates new remote branches: %s!") | |||
|
237 | % branchnames, | |||
|
238 | hint=_("use 'hg push --new-branch' to create" | |||
|
239 | " new remote branches")) | |||
|
240 | ||||
|
241 | # 2. Check for new heads. | |||
223 | # If there are more heads after the push than before, a suitable |
|
242 | # If there are more heads after the push than before, a suitable | |
224 | # error message, depending on unsynced status, is displayed. |
|
243 | # error message, depending on unsynced status, is displayed. | |
225 | error = None |
|
244 | error = None |
General Comments 0
You need to be logged in to leave comments.
Login now