hgext3rd/topic/flow.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 23 Apr 2019 12:29:45 +0200
branchmercurial-4.7
changeset 4559 c67a6998b8ba
parent 4263 35130e428ebd
child 4647 228caeb8b7af
permissions -rw-r--r--
test-compat: merge mercurial-4.8 into mercurial-4.7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3157
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     1
from __future__ import absolute_import
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     2
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     3
from mercurial import (
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
     4
    commands,
3157
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     5
    error,
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
     6
    exchange,
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
     7
    extensions,
3157
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     8
    node,
3158
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
     9
    phases,
3157
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    10
)
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    11
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    12
from mercurial.i18n import _
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    14
def enforcesinglehead(repo, tr):
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    15
    for name, heads in repo.filtered('visible').branchmap().iteritems():
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    16
        if len(heads) > 1:
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    17
            hexs = [node.short(n) for n in heads]
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    18
            raise error.Abort(_('%d heads on "%s"') % (len(heads), name),
f286eefbd20d topic: add an option to enforce a single head per name in a repository
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    19
                              hint=(', '.join(hexs)))
3158
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    20
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    21
def publishbarebranch(repo, tr):
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    22
    """Publish changeset without topic"""
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    23
    if 'node' not in tr.hookargs: # no new node
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    24
        return
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    25
    startnode = node.bin(tr.hookargs['node'])
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    26
    topublish = repo.revs('not public() and (%n:) - hidden() - topic()', startnode)
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    27
    if topublish:
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    28
        cl = repo.changelog
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    29
        nodes = [cl.node(r) for r in topublish]
678a9802c56b topic: add an option to automatically publish topic-less changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3157
diff changeset
    30
        repo._phasecache.advanceboundary(repo, tr, phases.public, nodes)
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    31
3235
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    32
def rejectuntopicedchangeset(repo, tr):
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    33
    """Reject the push if there are changeset without topic"""
3282
3675fe74521d topic: use 'hookargs' over 'tr.changes' for flow control
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3235
diff changeset
    34
    if 'node' not in tr.hookargs: # no new revs
3235
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    35
        return
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    36
3282
3675fe74521d topic: use 'hookargs' over 'tr.changes' for flow control
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3235
diff changeset
    37
    startnode = node.bin(tr.hookargs['node'])
3675fe74521d topic: use 'hookargs' over 'tr.changes' for flow control
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3235
diff changeset
    38
3235
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    39
    mode = repo.ui.config('experimental', 'topic-mode.server', 'ignore')
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    40
3282
3675fe74521d topic: use 'hookargs' over 'tr.changes' for flow control
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3235
diff changeset
    41
    untopiced = repo.revs('not public() and (%n:) - hidden() - topic()', startnode)
3235
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    42
    if untopiced:
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    43
        num = len(untopiced)
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    44
        fnode = repo[untopiced.first()].hex()[:10]
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    45
        if num == 1:
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    46
            msg = _("%s") % fnode
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    47
        else:
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    48
            msg = _("%s and %d more") % (fnode, num - 1)
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    49
        if mode == 'warning':
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    50
            fullmsg = _("pushed draft changeset without topic: %s\n")
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    51
            repo.ui.warn(fullmsg % msg)
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    52
        elif mode == 'enforce':
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    53
            fullmsg = _("rejecting draft changesets: %s")
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    54
            raise error.Abort(fullmsg % msg)
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    55
        else:
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    56
            repo.ui.warn(_("unknown 'topic-mode.server': %s\n" % mode))
8a772f0c54d9 topics: add a config to reject draft changeset without topic on a server
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3226
diff changeset
    57
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    58
def wrappush(orig, repo, remote, *args, **kwargs):
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    59
    """interpret the --publish flag and pass it to the push operation"""
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    60
    newargs = kwargs.copy()
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    61
    if kwargs.pop('publish', False):
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    62
        opargs = kwargs.get('opargs')
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    63
        if opargs is None:
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    64
            opargs = {}
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    65
        newargs['opargs'] = opargs.copy()
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    66
        newargs['opargs']['publish'] = True
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    67
    return orig(repo, remote, *args, **newargs)
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    68
3204
a342c454ccf3 pusoperation: wrap pushoperation __init__ directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3159
diff changeset
    69
def extendpushoperation(orig, self, *args, **kwargs):
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    70
    publish = kwargs.pop('publish', False)
3204
a342c454ccf3 pusoperation: wrap pushoperation __init__ directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3159
diff changeset
    71
    orig(self, *args, **kwargs)
a342c454ccf3 pusoperation: wrap pushoperation __init__ directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3159
diff changeset
    72
    self.publish = publish
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    73
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    74
def wrapphasediscovery(orig, pushop):
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    75
    orig(pushop)
3226
5dfe4e5cf9e4 topic: use more protective code to access publishing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3204
diff changeset
    76
    if getattr(pushop, 'publish', False):
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    77
        if not pushop.remotephases.publishing:
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    78
            unfi = pushop.repo.unfiltered()
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    79
            droots = pushop.remotephases.draftroots
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    80
            revset = '%ln and (not public() or %ln::)'
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    81
            future = list(unfi.set(revset, pushop.futureheads, droots))
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    82
            pushop.outdatedphases = future
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    83
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    84
def installpushflag(ui):
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    85
    entry = extensions.wrapcommand(commands.table, 'push', wrappush)
4245
419801742d08 topic: only add --publish flag to push if it's not already there
Anton Shestakov <av6@dwimlabs.net>
parents: 3282
diff changeset
    86
    if not any(opt for opt in entry[1] if opt[1] == 'publish'): # hg <= 4.9
419801742d08 topic: only add --publish flag to push if it's not already there
Anton Shestakov <av6@dwimlabs.net>
parents: 3282
diff changeset
    87
        entry[1].append(('', 'publish', False,
419801742d08 topic: only add --publish flag to push if it's not already there
Anton Shestakov <av6@dwimlabs.net>
parents: 3282
diff changeset
    88
                         _('push the changeset as public')))
3204
a342c454ccf3 pusoperation: wrap pushoperation __init__ directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3159
diff changeset
    89
    extensions.wrapfunction(exchange.pushoperation, '__init__',
a342c454ccf3 pusoperation: wrap pushoperation __init__ directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3159
diff changeset
    90
                            extendpushoperation)
3159
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    91
    extensions.wrapfunction(exchange, '_pushdiscoveryphase', wrapphasediscovery)
90515d0bfb08 push: add a --publish flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3158
diff changeset
    92
    exchange.pushdiscoverymapping['phase'] = exchange._pushdiscoveryphase