mercurial/discovery.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43106 d783f945a701
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    48 
    48 
    49     Please use findcommonoutgoing to compute the set of outgoing nodes to give
    49     Please use findcommonoutgoing to compute the set of outgoing nodes to give
    50     extensions a good hook into outgoing.
    50     extensions a good hook into outgoing.
    51     """
    51     """
    52 
    52 
    53     if not remote.capable('getbundle'):
    53     if not remote.capable(b'getbundle'):
    54         return treediscovery.findcommonincoming(repo, remote, heads, force)
    54         return treediscovery.findcommonincoming(repo, remote, heads, force)
    55 
    55 
    56     if heads:
    56     if heads:
    57         knownnode = repo.changelog.hasnode  # no nodemap until it is filtered
    57         knownnode = repo.changelog.hasnode  # no nodemap until it is filtered
    58         if all(knownnode(h) for h in heads):
    58         if all(knownnode(h) for h in heads):
   160     mayexclude = repo._phasecache.phaseroots[phases.secret] or repo.obsstore
   160     mayexclude = repo._phasecache.phaseroots[phases.secret] or repo.obsstore
   161     if not mayexclude:
   161     if not mayexclude:
   162         og.missingheads = onlyheads or repo.heads()
   162         og.missingheads = onlyheads or repo.heads()
   163     elif onlyheads is None:
   163     elif onlyheads is None:
   164         # use visible heads as it should be cached
   164         # use visible heads as it should be cached
   165         og.missingheads = repo.filtered("served").heads()
   165         og.missingheads = repo.filtered(b"served").heads()
   166         og.excluded = [ctx.node() for ctx in repo.set('secret() or extinct()')]
   166         og.excluded = [ctx.node() for ctx in repo.set(b'secret() or extinct()')]
   167     else:
   167     else:
   168         # compute common, missing and exclude secret stuff
   168         # compute common, missing and exclude secret stuff
   169         sets = repo.changelog.findcommonmissing(og.commonheads, onlyheads)
   169         sets = repo.changelog.findcommonmissing(og.commonheads, onlyheads)
   170         og._common, allmissing = sets
   170         og._common, allmissing = sets
   171         og._missing = missing = []
   171         og._missing = missing = []
   220         ctx = repo[n]
   220         ctx = repo[n]
   221         missingctx.add(ctx)
   221         missingctx.add(ctx)
   222         branches.add(ctx.branch())
   222         branches.add(ctx.branch())
   223 
   223 
   224     with remote.commandexecutor() as e:
   224     with remote.commandexecutor() as e:
   225         remotemap = e.callcommand('branchmap', {}).result()
   225         remotemap = e.callcommand(b'branchmap', {}).result()
   226 
   226 
   227     knownnode = cl.hasnode  # do not use nodemap until it is filtered
   227     knownnode = cl.hasnode  # do not use nodemap until it is filtered
   228     # A. register remote heads of branches which are in outgoing set
   228     # A. register remote heads of branches which are in outgoing set
   229     for branch, heads in remotemap.iteritems():
   229     for branch, heads in remotemap.iteritems():
   230         # don't add head info about branches which we don't have locally
   230         # don't add head info about branches which we don't have locally
   289     # all nodes in outgoing.missing are children of either:
   289     # all nodes in outgoing.missing are children of either:
   290     # - an element of oldheads
   290     # - an element of oldheads
   291     # - another element of outgoing.missing
   291     # - another element of outgoing.missing
   292     # - nullrev
   292     # - nullrev
   293     # This explains why the new head are very simple to compute.
   293     # This explains why the new head are very simple to compute.
   294     r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
   294     r = repo.set(b'heads(%ln + %ln)', oldheads, outgoing.missing)
   295     newheads = sorted(c.node() for c in r)
   295     newheads = sorted(c.node() for c in r)
   296     # set some unsynced head to issue the "unsynced changes" warning
   296     # set some unsynced head to issue the "unsynced changes" warning
   297     if inc:
   297     if inc:
   298         unsynced = [None]
   298         unsynced = [None]
   299     else:
   299     else:
   307     remote = pushop.remote
   307     remote = pushop.remote
   308     localbookmarks = repo._bookmarks
   308     localbookmarks = repo._bookmarks
   309 
   309 
   310     with remote.commandexecutor() as e:
   310     with remote.commandexecutor() as e:
   311         remotebookmarks = e.callcommand(
   311         remotebookmarks = e.callcommand(
   312             'listkeys', {'namespace': 'bookmarks',}
   312             b'listkeys', {b'namespace': b'bookmarks',}
   313         ).result()
   313         ).result()
   314 
   314 
   315     bookmarkedheads = set()
   315     bookmarkedheads = set()
   316 
   316 
   317     # internal config: bookmarks.pushing
   317     # internal config: bookmarks.pushing
   318     newbookmarks = [
   318     newbookmarks = [
   319         localbookmarks.expandname(b)
   319         localbookmarks.expandname(b)
   320         for b in pushop.ui.configlist('bookmarks', 'pushing')
   320         for b in pushop.ui.configlist(b'bookmarks', b'pushing')
   321     ]
   321     ]
   322 
   322 
   323     for bm in localbookmarks:
   323     for bm in localbookmarks:
   324         rnode = remotebookmarks.get(bm)
   324         rnode = remotebookmarks.get(bm)
   325         if rnode and rnode in repo:
   325         if rnode and rnode in repo:
   354     #   ancestral to an outgoing head
   354     #   ancestral to an outgoing head
   355     if remoteheads == [nullid]:
   355     if remoteheads == [nullid]:
   356         # remote is empty, nothing to check.
   356         # remote is empty, nothing to check.
   357         return
   357         return
   358 
   358 
   359     if remote.capable('branchmap'):
   359     if remote.capable(b'branchmap'):
   360         headssum = _headssummary(pushop)
   360         headssum = _headssummary(pushop)
   361     else:
   361     else:
   362         headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
   362         headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
   363     pushop.pushbranchmap = headssum
   363     pushop.pushbranchmap = headssum
   364     newbranches = [
   364     newbranches = [
   365         branch for branch, heads in headssum.iteritems() if heads[0] is None
   365         branch for branch, heads in headssum.iteritems() if heads[0] is None
   366     ]
   366     ]
   367     # 1. Check for new branches on the remote.
   367     # 1. Check for new branches on the remote.
   368     if newbranches and not newbranch:  # new branch requires --new-branch
   368     if newbranches and not newbranch:  # new branch requires --new-branch
   369         branchnames = ', '.join(sorted(newbranches))
   369         branchnames = b', '.join(sorted(newbranches))
   370         # Calculate how many of the new branches are closed branches
   370         # Calculate how many of the new branches are closed branches
   371         closedbranches = set()
   371         closedbranches = set()
   372         for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
   372         for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
   373             if isclosed:
   373             if isclosed:
   374                 closedbranches.add(tag)
   374                 closedbranches.add(tag)
   375         closedbranches = closedbranches & set(newbranches)
   375         closedbranches = closedbranches & set(newbranches)
   376         if closedbranches:
   376         if closedbranches:
   377             errmsg = _("push creates new remote branches: %s (%d closed)!") % (
   377             errmsg = _(b"push creates new remote branches: %s (%d closed)!") % (
   378                 branchnames,
   378                 branchnames,
   379                 len(closedbranches),
   379                 len(closedbranches),
   380             )
   380             )
   381         else:
   381         else:
   382             errmsg = _("push creates new remote branches: %s!") % branchnames
   382             errmsg = _(b"push creates new remote branches: %s!") % branchnames
   383         hint = _("use 'hg push --new-branch' to create new remote branches")
   383         hint = _(b"use 'hg push --new-branch' to create new remote branches")
   384         raise error.Abort(errmsg, hint=hint)
   384         raise error.Abort(errmsg, hint=hint)
   385 
   385 
   386     # 2. Find heads that we need not warn about
   386     # 2. Find heads that we need not warn about
   387     nowarnheads = _nowarnheads(pushop)
   387     nowarnheads = _nowarnheads(pushop)
   388 
   388 
   407                 heads = None
   407                 heads = None
   408             else:
   408             else:
   409                 heads = scmutil.nodesummaries(repo, unsyncedheads)
   409                 heads = scmutil.nodesummaries(repo, unsyncedheads)
   410             if heads is None:
   410             if heads is None:
   411                 repo.ui.status(
   411                 repo.ui.status(
   412                     _("remote has heads that are " "not known locally\n")
   412                     _(b"remote has heads that are " b"not known locally\n")
   413                 )
   413                 )
   414             elif branch is None:
   414             elif branch is None:
   415                 repo.ui.status(
   415                 repo.ui.status(
   416                     _("remote has heads that are " "not known locally: %s\n")
   416                     _(b"remote has heads that are " b"not known locally: %s\n")
   417                     % heads
   417                     % heads
   418                 )
   418                 )
   419             else:
   419             else:
   420                 repo.ui.status(
   420                 repo.ui.status(
   421                     _(
   421                     _(
   422                         "remote has heads on branch '%s' that are "
   422                         b"remote has heads on branch '%s' that are "
   423                         "not known locally: %s\n"
   423                         b"not known locally: %s\n"
   424                     )
   424                     )
   425                     % (branch, heads)
   425                     % (branch, heads)
   426                 )
   426                 )
   427         if remoteheads is None:
   427         if remoteheads is None:
   428             if len(newhs) > 1:
   428             if len(newhs) > 1:
   429                 dhs = list(newhs)
   429                 dhs = list(newhs)
   430                 if errormsg is None:
   430                 if errormsg is None:
   431                     errormsg = (
   431                     errormsg = (
   432                         _("push creates new branch '%s' with multiple heads")
   432                         _(b"push creates new branch '%s' with multiple heads")
   433                         % branch
   433                         % branch
   434                     )
   434                     )
   435                     hint = _(
   435                     hint = _(
   436                         "merge or"
   436                         b"merge or"
   437                         " see 'hg help push' for details about"
   437                         b" see 'hg help push' for details about"
   438                         " pushing new heads"
   438                         b" pushing new heads"
   439                     )
   439                     )
   440         elif len(newhs) > len(oldhs):
   440         elif len(newhs) > len(oldhs):
   441             # remove bookmarked or existing remote heads from the new heads list
   441             # remove bookmarked or existing remote heads from the new heads list
   442             dhs = sorted(newhs - nowarnheads - oldhs)
   442             dhs = sorted(newhs - nowarnheads - oldhs)
   443         if dhs:
   443         if dhs:
   444             if errormsg is None:
   444             if errormsg is None:
   445                 if branch not in ('default', None):
   445                 if branch not in (b'default', None):
   446                     errormsg = _(
   446                     errormsg = _(
   447                         "push creates new remote head %s " "on branch '%s'!"
   447                         b"push creates new remote head %s " b"on branch '%s'!"
   448                     ) % (short(dhs[0]), branch)
   448                     ) % (short(dhs[0]), branch)
   449                 elif repo[dhs[0]].bookmarks():
   449                 elif repo[dhs[0]].bookmarks():
   450                     errormsg = _(
   450                     errormsg = _(
   451                         "push creates new remote head %s " "with bookmark '%s'!"
   451                         b"push creates new remote head %s "
       
   452                         b"with bookmark '%s'!"
   452                     ) % (short(dhs[0]), repo[dhs[0]].bookmarks()[0])
   453                     ) % (short(dhs[0]), repo[dhs[0]].bookmarks()[0])
   453                 else:
   454                 else:
   454                     errormsg = _("push creates new remote head %s!") % short(
   455                     errormsg = _(b"push creates new remote head %s!") % short(
   455                         dhs[0]
   456                         dhs[0]
   456                     )
   457                     )
   457                 if unsyncedheads:
   458                 if unsyncedheads:
   458                     hint = _(
   459                     hint = _(
   459                         "pull and merge or"
   460                         b"pull and merge or"
   460                         " see 'hg help push' for details about"
   461                         b" see 'hg help push' for details about"
   461                         " pushing new heads"
   462                         b" pushing new heads"
   462                     )
   463                     )
   463                 else:
   464                 else:
   464                     hint = _(
   465                     hint = _(
   465                         "merge or"
   466                         b"merge or"
   466                         " see 'hg help push' for details about"
   467                         b" see 'hg help push' for details about"
   467                         " pushing new heads"
   468                         b" pushing new heads"
   468                     )
   469                     )
   469             if branch is None:
   470             if branch is None:
   470                 repo.ui.note(_("new remote heads:\n"))
   471                 repo.ui.note(_(b"new remote heads:\n"))
   471             else:
   472             else:
   472                 repo.ui.note(_("new remote heads on branch '%s':\n") % branch)
   473                 repo.ui.note(_(b"new remote heads on branch '%s':\n") % branch)
   473             for h in dhs:
   474             for h in dhs:
   474                 repo.ui.note(" %s\n" % short(h))
   475                 repo.ui.note(b" %s\n" % short(h))
   475     if errormsg:
   476     if errormsg:
   476         raise error.Abort(errormsg, hint=hint)
   477         raise error.Abort(errormsg, hint=hint)
   477 
   478 
   478 
   479 
   479 def _postprocessobsolete(pushop, futurecommon, candidate_newhs):
   480 def _postprocessobsolete(pushop, futurecommon, candidate_newhs):
   511         if h in unfi:
   512         if h in unfi:
   512             localcandidate.add(h)
   513             localcandidate.add(h)
   513         else:
   514         else:
   514             if successorsmarkers.get(h) is not None:
   515             if successorsmarkers.get(h) is not None:
   515                 msg = (
   516                 msg = (
   516                     'checkheads: remote head unknown locally has'
   517                     b'checkheads: remote head unknown locally has'
   517                     ' local marker: %s\n'
   518                     b' local marker: %s\n'
   518                 )
   519                 )
   519                 repo.ui.debug(msg % hex(h))
   520                 repo.ui.debug(msg % hex(h))
   520             unknownheads.add(h)
   521             unknownheads.add(h)
   521 
   522 
   522     # fast path the simple case
   523     # fast path the simple case
   531             newhs.add(nh)
   532             newhs.add(nh)
   532             continue
   533             continue
   533 
   534 
   534         # Get all revs/nodes on the branch exclusive to this head
   535         # Get all revs/nodes on the branch exclusive to this head
   535         # (already filtered heads are "ignored"))
   536         # (already filtered heads are "ignored"))
   536         branchrevs = unfi.revs('only(%n, (%ln+%ln))', nh, localcandidate, newhs)
   537         branchrevs = unfi.revs(
       
   538             b'only(%n, (%ln+%ln))', nh, localcandidate, newhs
       
   539         )
   537         branchnodes = [tonode(r) for r in branchrevs]
   540         branchnodes = [tonode(r) for r in branchrevs]
   538 
   541 
   539         # The branch won't be hidden on the remote if
   542         # The branch won't be hidden on the remote if
   540         # * any part of it is public,
   543         # * any part of it is public,
   541         # * any part of it is considered part of the result by previous logic,
   544         # * any part of it is considered part of the result by previous logic,