hgext3rd/topic/destination.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 14 Jul 2017 01:32:34 +0200
changeset 2738 3f27fe80be26
parent 2653 13313d0cab71
child 2891 b18d2b2f18a6
permissions -rw-r--r--
prev: issue a proper error when reaching repository root (and adds the associated test)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1933
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     1
from __future__ import absolute_import
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     2
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
     3
from mercurial.i18n import _
1933
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     4
from mercurial import (
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     5
    bookmarks,
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     6
    destutil,
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     7
    error,
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     8
    extensions,
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
     9
    util,
ca8674a8fce4 destination: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1912
diff changeset
    10
)
1986
042356d5ba59 ngtip: rely on topicmap for 'ngtip'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1984
diff changeset
    11
from . import topicmap
1983
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    12
from .evolvebits import builddependencies
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    13
1962
c00815786813 compat: adapt to the new destspace argument of destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1941
diff changeset
    14
def _destmergebranch(orig, repo, action='merge', sourceset=None,
c00815786813 compat: adapt to the new destspace argument of destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1941
diff changeset
    15
                     onheadcheck=True, destspace=None):
1967
c5d4e856ad0e destination: add an XXX about handling destspace in destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1964
diff changeset
    16
    # XXX: take destspace into account
1984
2a07df823588 destination: honor the sourceset argument of _destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1983
diff changeset
    17
    if sourceset is None:
2006
c817efec4afc flake8: fix E111 style
Sean Farley <sean@farley.io>
parents: 2005
diff changeset
    18
        p1 = repo['.']
1984
2a07df823588 destination: honor the sourceset argument of _destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1983
diff changeset
    19
    else:
2a07df823588 destination: honor the sourceset argument of _destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1983
diff changeset
    20
        # XXX: using only the max here is flacky. That code should eventually
2a07df823588 destination: honor the sourceset argument of _destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1983
diff changeset
    21
        # be updated to take care of the whole sourceset.
2006
c817efec4afc flake8: fix E111 style
Sean Farley <sean@farley.io>
parents: 2005
diff changeset
    22
        p1 = repo[max(sourceset)]
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    23
    top = p1.topic()
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    24
    if top:
1983
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    25
        revs = repo.revs('topic(%s) - obsolete()', top)
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    26
        deps, rdeps = builddependencies(repo, revs)
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    27
        heads = [r for r in revs if not rdeps[r]]
1981
b467fe430404 destmerge: honor the 'onheadcheck' argument
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1980
diff changeset
    28
        if onheadcheck and p1.rev() not in heads:
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    29
            raise error.Abort(_("not at topic head, update or explicit"))
1983
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    30
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    31
        # prune heads above the source
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    32
        otherheads = set(heads)
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    33
        pool = set([p1.rev()])
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    34
        while pool:
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    35
            current = pool.pop()
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    36
            otherheads.discard(current)
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    37
            pool.update(rdeps[current])
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    38
        if not otherheads:
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    39
            # nothing to do at the topic level
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    40
            bhead = ngtip(repo, p1.branch(), all=True)
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    41
            if not bhead:
1980
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    42
                raise error.NoMergeDestAbort(_("nothing to merge"))
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    43
            elif 1 == len(bhead):
1986
042356d5ba59 ngtip: rely on topicmap for 'ngtip'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1984
diff changeset
    44
                return bhead[0]
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    45
            else:
1980
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    46
                msg = _("branch '%s' has %d heads "
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    47
                        "- please merge with an explicit rev")
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    48
                hint = _("run 'hg heads .' to see heads")
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    49
                raise error.ManyMergeDestAbort(msg % (p1.branch(), len(bhead)),
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    50
                                               hint=hint)
1983
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    51
        elif len(otherheads) == 1:
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    52
            return otherheads.pop()
4864ddc4c6d9 destmerge: improve topic head computation and handling
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1981
diff changeset
    53
        else:
1980
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    54
            msg = _("topic '%s' has %d heads "
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    55
                    "- please merge with an explicit rev") % (top, len(heads))
3c4a20244771 destination: use the correct abort class for error
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1969
diff changeset
    56
            raise error.ManyMergeDestAbort(msg)
1962
c00815786813 compat: adapt to the new destspace argument of destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1941
diff changeset
    57
    if len(getattr(orig, 'func_defaults', ())) == 3: # version hg-3.7
1878
c44f161575ba compat: adapt to change in mercurial core
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1871
diff changeset
    58
        return orig(repo, action, sourceset, onheadcheck)
1962
c00815786813 compat: adapt to the new destspace argument of destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1941
diff changeset
    59
    if 3 < len(getattr(orig, 'func_defaults', ())): # version hg-3.8 and above
c00815786813 compat: adapt to the new destspace argument of destmerge
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1941
diff changeset
    60
        return orig(repo, action, sourceset, onheadcheck, destspace=destspace)
1878
c44f161575ba compat: adapt to change in mercurial core
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1871
diff changeset
    61
    else:
c44f161575ba compat: adapt to change in mercurial core
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1871
diff changeset
    62
        return orig(repo)
1871
58ef5699fb35 merge: use topic to pick default destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1870
diff changeset
    63
2017
dd1055f38397 compat: handle difference of signature for update destination hooks
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2006
diff changeset
    64
def _destupdatetopic(repo, clean, check=None):
1892
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    65
    """decide on an update destination from current topic"""
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    66
    movemark = node = None
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    67
    topic = repo.currenttopic
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    68
    revs = repo.revs('.::topic("%s")' % topic)
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    69
    if not revs:
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    70
        return None, None, None
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    71
    node = revs.last()
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    72
    if bookmarks.isactivewdirparent(repo):
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    73
        movemark = repo['.'].node()
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    74
    return node, movemark, None
b1fadc089b82 update: change default update destination to take topic in account
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1891
diff changeset
    75
1911
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    76
def desthistedit(orig, ui, repo):
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    77
    if not (ui.config('histedit', 'defaultrev', None) is None
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    78
            and repo.currenttopic):
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    79
        return orig(ui, repo)
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    80
    revs = repo.revs('::. and stack()')
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    81
    if revs:
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    82
        return revs.min()
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    83
    return None
442a7cb8404e histedit: restrict default edited set to current topic when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1902
diff changeset
    84
1870
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    85
def ngtip(repo, branch, all=False):
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    86
    """tip new generation"""
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    87
    ## search for untopiced heads of branch
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    88
    # could be heads((::branch(x) - topic()))
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    89
    # but that is expensive
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    90
    #
8dd5200b4086 topic: introduce a 'ngtip' concept
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    91
    # we should write plain code instead
2653
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    92
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    93
    tmap = topicmap.gettopicrepo(repo).branchmap()
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    94
    if branch not in tmap:
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    95
        return []
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    96
    elif all:
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    97
        return tmap.branchheads(branch)
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    98
    else:
13313d0cab71 topicmap: massive rework
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2017
diff changeset
    99
        return [tmap.branchtip(branch)]
1938
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   100
1941
7eb737b7a902 destination: rename 'setupdest' to 'modsetup'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1940
diff changeset
   101
def modsetup(ui):
1940
6d53f81d3b64 destination: document 'setupdest'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1939
diff changeset
   102
    """run a uisetup time to install all destinations wrapping"""
1938
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   103
    if util.safehasattr(destutil, '_destmergebranch'):
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   104
        extensions.wrapfunction(destutil, '_destmergebranch', _destmergebranch)
1969
a604423c1500 compat: tolerate missing rebase extension
timeless@gmail.com
parents: 1967
diff changeset
   105
    try:
a604423c1500 compat: tolerate missing rebase extension
timeless@gmail.com
parents: 1967
diff changeset
   106
        rebase = extensions.find('rebase')
a604423c1500 compat: tolerate missing rebase extension
timeless@gmail.com
parents: 1967
diff changeset
   107
    except KeyError:
a604423c1500 compat: tolerate missing rebase extension
timeless@gmail.com
parents: 1967
diff changeset
   108
        rebase = None
1938
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   109
    if (util.safehasattr(rebase, '_destrebase')
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   110
            # logic not shared with merge yet < hg-3.8
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   111
            and not util.safehasattr(rebase, '_definesets')):
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   112
        extensions.wrapfunction(rebase, '_destrebase', _destmergebranch)
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   113
    if util.safehasattr(destutil, 'destupdatesteps'):
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   114
        bridx = destutil.destupdatesteps.index('branch')
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   115
        destutil.destupdatesteps.insert(bridx, 'topic')
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   116
        destutil.destupdatestepmap['topic'] = _destupdatetopic
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   117
    if util.safehasattr(destutil, 'desthistedit'):
7e31d3e79806 destination: make sure 'setupdest' is the latest function in the module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1933
diff changeset
   118
        extensions.wrapfunction(destutil, 'desthistedit', desthistedit)