hgext3rd/topic/destination.py
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Sat, 13 Aug 2016 00:13:05 +0200
changeset 1974 20fb4195bfc4
parent 1969 a604423c1500
child 1980 3c4a20244771
permissions -rw-r--r--
topic: extract the code listing all topics The code will become more complexe with formatter support and additional data in the verbose output. We extract the code in its own function first.

from __future__ import absolute_import

from mercurial.i18n import _
from mercurial import (
    bookmarks,
    destutil,
    error,
    extensions,
    util,
)

def _destmergebranch(orig, repo, action='merge', sourceset=None,
                     onheadcheck=True, destspace=None):
    # XXX: take destspace into account
    p1 = repo['.']
    top = p1.topic()
    if top:
        heads = repo.revs('heads(topic(.)::topic(.))')
        if p1.rev() not in heads:
            raise error.Abort(_("not at topic head, update or explicit"))
        elif 1 == len(heads):
            # should look at all branch involved but... later
            bhead = ngtip(repo, p1.branch(), all=True)
            if not bhead:
                raise error.Abort(_("nothing to merge"))
            elif 1 == len(bhead):
                return bhead.first()
            else:
                raise error.Abort(_("branch '%s' has %d heads - "
                                    "please merge with an explicit rev")
                                  % (p1.branch(), len(bhead)),
                                  hint=_("run 'hg heads .' to see heads"))
        elif 2 == len(heads):
            heads = [r for r in heads if r != p1.rev()]
            # XXX: bla bla bla bla bla
            if 1 < len(heads):
                raise error.Abort(_('working directory not at a head revision'),
                                  hint=_("use 'hg update' or merge with an "
                                         "explicit revision"))
            return heads[0]
        elif 2 < len(heads):
            raise error.Abort(_("topic '%s' has %d heads - "
                                "please merge with an explicit rev")
                              % (top, len(heads)))
        else:
            assert False # that's impossible
    if len(getattr(orig, 'func_defaults', ())) == 3: # version hg-3.7
        return orig(repo, action, sourceset, onheadcheck)
    if 3 < len(getattr(orig, 'func_defaults', ())): # version hg-3.8 and above
        return orig(repo, action, sourceset, onheadcheck, destspace=destspace)
    else:
        return orig(repo)

def _destupdatetopic(repo, clean, check):
    """decide on an update destination from current topic"""
    movemark = node = None
    topic = repo.currenttopic
    revs = repo.revs('.::topic("%s")' % topic)
    if not revs:
        return None, None, None
    node = revs.last()
    if bookmarks.isactivewdirparent(repo):
        movemark = repo['.'].node()
    return node, movemark, None

def desthistedit(orig, ui, repo):
    if not (ui.config('histedit', 'defaultrev', None) is None
            and repo.currenttopic):
        return orig(ui, repo)
    revs = repo.revs('::. and stack()')
    if revs:
        return revs.min()
    return None

def ngtip(repo, branch, all=False):
    """tip new generation"""
    ## search for untopiced heads of branch
    # could be heads((::branch(x) - topic()))
    # but that is expensive
    #
    # we should write plain code instead
    subquery = '''heads(
                    parents(
                       ancestor(
                         (head() and branch(%s)
                         or (topic() and branch(%s)))))
                   ::(head() and branch(%s))
                   - topic())'''
    if not all:
        subquery = 'max(%s)' % subquery
    return repo.revs(subquery, branch, branch, branch)

def modsetup(ui):
    """run a uisetup time to install all destinations wrapping"""
    if util.safehasattr(destutil, '_destmergebranch'):
        extensions.wrapfunction(destutil, '_destmergebranch', _destmergebranch)
    try:
        rebase = extensions.find('rebase')
    except KeyError:
        rebase = None
    if (util.safehasattr(rebase, '_destrebase')
            # logic not shared with merge yet < hg-3.8
            and not util.safehasattr(rebase, '_definesets')):
        extensions.wrapfunction(rebase, '_destrebase', _destmergebranch)
    if util.safehasattr(destutil, 'destupdatesteps'):
        bridx = destutil.destupdatesteps.index('branch')
        destutil.destupdatesteps.insert(bridx, 'topic')
        destutil.destupdatestepmap['topic'] = _destupdatetopic
    if util.safehasattr(destutil, 'desthistedit'):
        extensions.wrapfunction(destutil, 'desthistedit', desthistedit)