hgext3rd/evolve/headchecking.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Wed, 11 Mar 2020 23:56:11 +0100
branchstable
changeset 5272 b20d04641c0f
parent 5268 11c359b4071d
child 5273 f560d23639e1
permissions -rw-r--r--
head-checking: ignore obsolete section when checking for single heads This overwrite the core code that enforce single heads to ignore obsolete section. That way older obsolete version of a branch no longer prevent the new version to be pushed.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5268
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     1
from __future__ import absolute_import
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     2
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     3
import functools
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     4
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     5
from mercurial import (
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     6
    discovery,
5272
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
     7
    error,
5268
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     8
    extensions,
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     9
    phases,
5272
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
    10
    scmutil,
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
    11
    util,
5268
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    12
)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
5272
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
    14
from mercurial.i18n import _
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
    15
5268
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    16
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    17
from . import (
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    18
    compat,
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    19
    exthelper,
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    20
)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    21
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    22
eh = exthelper.exthelper()
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    23
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    24
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    25
@eh.uisetup
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    26
def uisetup(ui):
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    27
    extensions.wrapfunction(discovery, '_postprocessobsolete', _postprocessobsolete)
5272
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
    28
    extensions.wrapfunction(scmutil, 'enforcesinglehead', enforcesinglehead)
5268
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    29
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    30
def branchinfo(pushop, repo, node):
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    31
    return repo[node].branch()
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    32
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    33
# taken from 7d5455b988ec + branchinfo abstraction.
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    34
def _postprocessobsolete(orig, pushop, futurecommon, candidate_newhs):
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    35
    """post process the list of new heads with obsolescence information
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    36
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    37
    Exists as a sub-function to contain the complexity and allow extensions to
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    38
    experiment with smarter logic.
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    39
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    40
    Returns (newheads, discarded_heads) tuple
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    41
    """
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    42
    pushingmarkerfor = discovery.pushingmarkerfor
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    43
    # known issue
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    44
    #
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    45
    # * We "silently" skip processing on all changeset unknown locally
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    46
    #
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    47
    # * if <nh> is public on the remote, it won't be affected by obsolete
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    48
    #     marker and a new is created
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    49
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    50
    # define various utilities and containers
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    51
    repo = pushop.repo
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    52
    unfi = repo.unfiltered()
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    53
    torev = compat.getgetrev(unfi.changelog)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    54
    public = phases.public
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    55
    getphase = unfi._phasecache.phase
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    56
    ispublic = lambda r: getphase(unfi, r) == public
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    57
    ispushed = lambda n: torev(n) in futurecommon
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    58
    hasoutmarker = functools.partial(pushingmarkerfor, unfi.obsstore, ispushed)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    59
    successorsmarkers = unfi.obsstore.successors
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    60
    newhs = set()  # final set of new heads
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    61
    discarded = set()  # new head of fully replaced branch
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    62
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    63
    localcandidate = set()  # candidate heads known locally
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    64
    unknownheads = set()  # candidate heads unknown locally
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    65
    for h in candidate_newhs:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    66
        if h in unfi:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    67
            localcandidate.add(h)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    68
        else:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    69
            if successorsmarkers.get(h) is not None:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    70
                msg = (
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    71
                    b'checkheads: remote head unknown locally has'
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    72
                    b' local marker: %s\n'
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    73
                )
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    74
                repo.ui.debug(msg % hex(h))
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    75
            unknownheads.add(h)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    76
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    77
    # fast path the simple case
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    78
    if len(localcandidate) == 1:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    79
        return unknownheads | set(candidate_newhs), set()
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    80
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    81
    # actually process branch replacement
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    82
    while localcandidate:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    83
        nh = localcandidate.pop()
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    84
        current_branch = branchinfo(pushop, unfi, nh)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    85
        # run this check early to skip the evaluation of the whole branch
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    86
        if torev(nh) in futurecommon or ispublic(torev(nh)):
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    87
            newhs.add(nh)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    88
            continue
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    89
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    90
        # Get all revs/nodes on the branch exclusive to this head
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    91
        # (already filtered heads are "ignored"))
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    92
        branchrevs = unfi.revs(
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    93
            b'only(%n, (%ln+%ln))', nh, localcandidate, newhs
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    94
        )
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    95
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    96
        branchnodes = []
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    97
        for r in branchrevs:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    98
            ctx = unfi[r]
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    99
            if ctx.branch() == current_branch:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   100
                branchnodes.append(ctx.node())
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   101
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   102
        # The branch won't be hidden on the remote if
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   103
        # * any part of it is public,
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   104
        # * any part of it is considered part of the result by previous logic,
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   105
        # * if we have no markers to push to obsolete it.
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   106
        if (
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   107
            any(ispublic(torev(n)) for n in branchnodes)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   108
            or any(torev(n) in futurecommon for n in branchnodes)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   109
            or any(not hasoutmarker(n) for n in branchnodes)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   110
        ):
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   111
            newhs.add(nh)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   112
        else:
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   113
            # note: there is a corner case if there is a merge in the branch.
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   114
            # we might end up with -more- heads.  However, these heads are not
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   115
            # "added" by the push, but more by the "removal" on the remote so I
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   116
            # think is a okay to ignore them,
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   117
            discarded.add(nh)
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   118
    newhs |= unknownheads
11c359b4071d head-checking: backport fix from 7d5455b988ec
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   119
    return newhs, discarded
5272
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   120
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   121
def _get_branch_name(ctx):
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   122
    # make it easy for extension with the branch logic there
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   123
    branch = ctx.branch()
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   124
    if util.safehasattr(ctx, 'topic'):
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   125
        topic = ctx.topic()
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   126
        if topic:
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   127
            branch = "%s:%s" % (branch, topic)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   128
    return branch
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   129
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   130
def _filter_obsolete_heads(repo, heads):
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   131
    """filter heads to return non-obsolete ones
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   132
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   133
    Given a list of heads (on the same named branch) return a new list of heads
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   134
    where the obsolete part have been skimmed out.
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   135
    """
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   136
    new_heads = []
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   137
    old_heads = heads[:]
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   138
    while old_heads:
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   139
        rh = old_heads.pop()
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   140
        ctx = repo[rh]
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   141
        current_name = _get_branch_name(ctx)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   142
        # run this check early to skip the evaluation of the whole branch
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   143
        if not ctx.obsolete():
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   144
            new_heads.append(rh)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   145
            continue
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   146
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   147
        # Get all revs/nodes on the branch exclusive to this head
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   148
        # (already filtered heads are "ignored"))
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   149
        sections_revs = repo.revs(
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   150
            b'only(%d, (%ld+%ld))', rh, old_heads, new_heads,
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   151
        )
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   152
        keep_revs = []
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   153
        for r in sections_revs:
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   154
            ctx = repo[r]
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   155
            if ctx.obsolete():
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   156
                continue
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   157
            if _get_branch_name(ctx) != current_name:
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   158
                continue
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   159
            keep_revs.append(r)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   160
        for h in repo.revs(b'heads(%ld and (::%ld))', sections_revs, keep_revs):
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   161
            new_heads.append(h)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   162
    new_heads.sort()
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   163
    return new_heads
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   164
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   165
def enforcesinglehead(orig, repo, tr, desc, accountclosed=False):
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   166
    """check that no named branch has multiple heads"""
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   167
    nodesummaries = scmutil.nodesummaries
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   168
    if desc in (b'strip', b'repair'):
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   169
        # skip the logic during strip
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   170
        return
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   171
    visible = repo.filtered(b'visible')
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   172
    # possible improvement: we could restrict the check to affected branch
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   173
    bm = visible.branchmap()
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   174
    cl = repo.changelog
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   175
    to_rev = cl.rev
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   176
    to_node = cl.node
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   177
    for name in bm:
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   178
        all_heads = bm.branchheads(name, closed=accountclosed)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   179
        all_heads = [to_rev(n) for n in all_heads]
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   180
        heads = _filter_obsolete_heads(repo, all_heads)
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   181
        heads = [to_node(r) for r in heads]
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   182
        if len(heads) > 1:
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   183
            msg = _(b'rejecting multiple heads on branch "%s"')
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   184
            msg %= name
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   185
            hint = _(b'%d heads: %s')
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   186
            hint %= (len(heads), nodesummaries(repo, heads))
b20d04641c0f head-checking: ignore obsolete section when checking for single heads
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5268
diff changeset
   187
            raise error.Abort(msg, hint=hint)