hgext3rd/topic/flow.py
author Sushil khanchi <sushilkhanchi97@gmail.com>
Thu, 07 Mar 2019 01:47:14 +0530
branchstable
changeset 4426 7d97e08d13a0
parent 4263 35130e428ebd
child 4647 228caeb8b7af
permissions -rw-r--r--
evolve: fix the dirstate after setting parents with dirty wdir (issue5930) Before this patch, during an interrupted evolve it can be confused about copies. This patch fix the dirstate when parents are changed using dirstate.setparents() with a dirty wdir. Changes in test file reflect the fixed behaviour.

from __future__ import absolute_import

from mercurial import (
    commands,
    error,
    exchange,
    extensions,
    node,
    phases,
)

from mercurial.i18n import _

def enforcesinglehead(repo, tr):
    for name, heads in repo.filtered('visible').branchmap().iteritems():
        if len(heads) > 1:
            hexs = [node.short(n) for n in heads]
            raise error.Abort(_('%d heads on "%s"') % (len(heads), name),
                              hint=(', '.join(hexs)))

def publishbarebranch(repo, tr):
    """Publish changeset without topic"""
    if 'node' not in tr.hookargs: # no new node
        return
    startnode = node.bin(tr.hookargs['node'])
    topublish = repo.revs('not public() and (%n:) - hidden() - topic()', startnode)
    if topublish:
        cl = repo.changelog
        nodes = [cl.node(r) for r in topublish]
        repo._phasecache.advanceboundary(repo, tr, phases.public, nodes)

def rejectuntopicedchangeset(repo, tr):
    """Reject the push if there are changeset without topic"""
    if 'node' not in tr.hookargs: # no new revs
        return

    startnode = node.bin(tr.hookargs['node'])

    mode = repo.ui.config('experimental', 'topic-mode.server', 'ignore')

    untopiced = repo.revs('not public() and (%n:) - hidden() - topic()', startnode)
    if untopiced:
        num = len(untopiced)
        fnode = repo[untopiced.first()].hex()[:10]
        if num == 1:
            msg = _("%s") % fnode
        else:
            msg = _("%s and %d more") % (fnode, num - 1)
        if mode == 'warning':
            fullmsg = _("pushed draft changeset without topic: %s\n")
            repo.ui.warn(fullmsg % msg)
        elif mode == 'enforce':
            fullmsg = _("rejecting draft changesets: %s")
            raise error.Abort(fullmsg % msg)
        else:
            repo.ui.warn(_("unknown 'topic-mode.server': %s\n" % mode))

def wrappush(orig, repo, remote, *args, **kwargs):
    """interpret the --publish flag and pass it to the push operation"""
    newargs = kwargs.copy()
    if kwargs.pop('publish', False):
        opargs = kwargs.get('opargs')
        if opargs is None:
            opargs = {}
        newargs['opargs'] = opargs.copy()
        newargs['opargs']['publish'] = True
    return orig(repo, remote, *args, **newargs)

def extendpushoperation(orig, self, *args, **kwargs):
    publish = kwargs.pop('publish', False)
    orig(self, *args, **kwargs)
    self.publish = publish

def wrapphasediscovery(orig, pushop):
    orig(pushop)
    if getattr(pushop, 'publish', False):
        if not pushop.remotephases.publishing:
            unfi = pushop.repo.unfiltered()
            droots = pushop.remotephases.draftroots
            revset = '%ln and (not public() or %ln::)'
            future = list(unfi.set(revset, pushop.futureheads, droots))
            pushop.outdatedphases = future

def installpushflag(ui):
    entry = extensions.wrapcommand(commands.table, 'push', wrappush)
    if not any(opt for opt in entry[1] if opt[1] == 'publish'): # hg <= 4.9
        entry[1].append(('', 'publish', False,
                         _('push the changeset as public')))
    extensions.wrapfunction(exchange.pushoperation, '__init__',
                            extendpushoperation)
    extensions.wrapfunction(exchange, '_pushdiscoveryphase', wrapphasediscovery)
    exchange.pushdiscoverymapping['phase'] = exchange._pushdiscoveryphase