mercurial/discovery.py
changeset 20381 fff0a71f8177
parent 20225 d2704c48f417
child 20398 2bc520bd0ce0
equal deleted inserted replaced
20380:c697b70f295f 20381:fff0a71f8177
   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"