152 |
152 |
153 return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping |
153 return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping |
154 |
154 |
155 - branch: the branch name |
155 - branch: the branch name |
156 - remoteheads: the list of remote heads known locally |
156 - remoteheads: the list of remote heads known locally |
157 None is the branch is new |
157 None if the branch is new |
158 - newheads: the new remote heads (known locally) with outgoing pushed |
158 - newheads: the new remote heads (known locally) with outgoing pushed |
159 - unsyncedheads: the list of remote heads unknown locally. |
159 - unsyncedheads: the list of remote heads unknown locally. |
160 """ |
160 """ |
161 cl = repo.changelog |
161 cl = repo.changelog |
162 headssum = {} |
162 headssum = {} |
248 raise util.Abort(_("push creates new remote branches: %s!") |
248 raise util.Abort(_("push creates new remote branches: %s!") |
249 % branchnames, |
249 % branchnames, |
250 hint=_("use 'hg push --new-branch' to create" |
250 hint=_("use 'hg push --new-branch' to create" |
251 " new remote branches")) |
251 " new remote branches")) |
252 |
252 |
253 # 2 compute newly pushed bookmarks. We |
253 # 2. Compute newly pushed bookmarks. We don't warn about bookmarked heads. |
254 # we don't warned about bookmarked heads. |
|
255 localbookmarks = repo._bookmarks |
254 localbookmarks = repo._bookmarks |
256 remotebookmarks = remote.listkeys('bookmarks') |
255 remotebookmarks = remote.listkeys('bookmarks') |
257 bookmarkedheads = set() |
256 bookmarkedheads = set() |
258 for bm in localbookmarks: |
257 for bm in localbookmarks: |
259 rnode = remotebookmarks.get(bm) |
258 rnode = remotebookmarks.get(bm) |
272 unsynced = False |
271 unsynced = False |
273 allmissing = set(outgoing.missing) |
272 allmissing = set(outgoing.missing) |
274 allfuturecommon = set(c.node() for c in repo.set('%ld', outgoing.common)) |
273 allfuturecommon = set(c.node() for c in repo.set('%ld', outgoing.common)) |
275 allfuturecommon.update(allmissing) |
274 allfuturecommon.update(allmissing) |
276 for branch, heads in sorted(headssum.iteritems()): |
275 for branch, heads in sorted(headssum.iteritems()): |
277 candidate_newhs = set(heads[1]) |
276 remoteheads, newheads, unsyncedheads = heads |
|
277 candidate_newhs = set(newheads) |
278 # add unsynced data |
278 # add unsynced data |
279 if heads[0] is None: |
279 if remoteheads is None: |
280 oldhs = set() |
280 oldhs = set() |
281 else: |
281 else: |
282 oldhs = set(heads[0]) |
282 oldhs = set(remoteheads) |
283 oldhs.update(heads[2]) |
283 oldhs.update(unsyncedheads) |
284 candidate_newhs.update(heads[2]) |
284 candidate_newhs.update(unsyncedheads) |
285 dhs = None |
285 dhs = None # delta heads, the new heads on branch |
286 discardedheads = set() |
286 discardedheads = set() |
287 if repo.obsstore: |
287 if repo.obsstore: |
288 # remove future heads which are actually obsolete by another |
288 # remove future heads which are actually obsoleted by another |
289 # pushed element: |
289 # pushed element: |
290 # |
290 # |
291 # XXX as above, There are several cases this case does not handle |
291 # XXX as above, There are several cases this case does not handle |
292 # XXX properly |
292 # XXX properly |
293 # |
293 # |
295 # and a new is created |
295 # and a new is created |
296 # |
296 # |
297 # (2) if the new heads have ancestors which are not obsolete and |
297 # (2) if the new heads have ancestors which are not obsolete and |
298 # not ancestors of any other heads we will have a new head too. |
298 # not ancestors of any other heads we will have a new head too. |
299 # |
299 # |
300 # This two case will be easy to handle for know changeset but much |
300 # These two cases will be easy to handle for known changeset but |
301 # more tricky for unsynced changes. |
301 # much more tricky for unsynced changes. |
302 newhs = set() |
302 newhs = set() |
303 for nh in candidate_newhs: |
303 for nh in candidate_newhs: |
304 if nh in repo and repo[nh].phase() <= phases.public: |
304 if nh in repo and repo[nh].phase() <= phases.public: |
305 newhs.add(nh) |
305 newhs.add(nh) |
306 else: |
306 else: |
310 break |
310 break |
311 else: |
311 else: |
312 newhs.add(nh) |
312 newhs.add(nh) |
313 else: |
313 else: |
314 newhs = candidate_newhs |
314 newhs = candidate_newhs |
315 if [h for h in heads[2] if h not in discardedheads]: |
315 if [h for h in unsyncedheads if h not in discardedheads]: |
316 unsynced = True |
316 unsynced = True |
317 if heads[0] is None: |
317 if remoteheads is None: |
318 if 1 < len(newhs): |
318 if len(newhs) > 1: |
319 dhs = list(newhs) |
319 dhs = list(newhs) |
320 if error is None: |
320 if error is None: |
321 error = (_("push creates new branch '%s' " |
321 error = (_("push creates new branch '%s' " |
322 "with multiple heads") % (branch)) |
322 "with multiple heads") % (branch)) |
323 hint = _("merge or" |
323 hint = _("merge or" |
324 " see \"hg help push\" for details about" |
324 " see \"hg help push\" for details about" |
325 " pushing new heads") |
325 " pushing new heads") |
326 elif len(newhs) > len(oldhs): |
326 elif len(newhs) > len(oldhs): |
327 # strip updates to existing remote heads from the new heads list |
327 # remove bookmarked or existing remote heads from the new heads list |
328 dhs = sorted(newhs - bookmarkedheads - oldhs) |
328 dhs = sorted(newhs - bookmarkedheads - oldhs) |
329 if dhs: |
329 if dhs: |
330 if error is None: |
330 if error is None: |
331 if branch not in ('default', None): |
331 if branch not in ('default', None): |
332 error = _("push creates new remote head %s " |
332 error = _("push creates new remote head %s " |
333 "on branch '%s'!") % (short(dhs[0]), branch) |
333 "on branch '%s'!") % (short(dhs[0]), branch) |
334 else: |
334 else: |
335 error = _("push creates new remote head %s!" |
335 error = _("push creates new remote head %s!" |
336 ) % short(dhs[0]) |
336 ) % short(dhs[0]) |
337 if heads[2]: # unsynced |
337 if unsyncedheads: |
338 hint = _("pull and merge or" |
338 hint = _("pull and merge or" |
339 " see \"hg help push\" for details about" |
339 " see \"hg help push\" for details about" |
340 " pushing new heads") |
340 " pushing new heads") |
341 else: |
341 else: |
342 hint = _("merge or" |
342 hint = _("merge or" |