hgext3rd/topic/stack.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 05 Jan 2018 22:17:27 +0100
changeset 3365 911c91ce686f
parent 3278 e4c0332ecee4
child 3371 753e5ebabe7d
permissions -rw-r--r--
caches: record 'desc' attribute on transaction This is useful to know if a transaction if server side or not.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1895
c8e4c6e03957 stack: add a very first version of stack display with 'hg topic --list'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
     1
# stack.py - code related to stack workflow
c8e4c6e03957 stack: add a very first version of stack display with 'hg topic --list'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
     2
#
c8e4c6e03957 stack: add a very first version of stack display with 'hg topic --list'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
     3
# This software may be used and distributed according to the terms of the
c8e4c6e03957 stack: add a very first version of stack display with 'hg topic --list'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
     4
# GNU General Public License version 2 or any later version.
1995
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
     5
from mercurial.i18n import _
1936
31583ddda6d9 stack: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1925
diff changeset
     6
from mercurial import (
1985
03d6b685c16a topic: list the number of 'behind' changeset when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1982
diff changeset
     7
    destutil,
2838
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
     8
    context,
1936
31583ddda6d9 stack: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1925
diff changeset
     9
    error,
1961
d9c7fced94fc stack: prevent crash when topic is rooted on nullid
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1957
diff changeset
    10
    node,
2919
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    11
    phases,
3123
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    12
    obsolete,
2838
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
    13
    util,
1936
31583ddda6d9 stack: move to new style import
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1925
diff changeset
    14
)
3278
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
    15
from .evolvebits import (
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
    16
    _singlesuccessor,
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
    17
    MultipleSuccessorsError,
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
    18
    builddependencies,
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
    19
)
1895
c8e4c6e03957 stack: add a very first version of stack display with 'hg topic --list'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff changeset
    20
2750
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
    21
short = node.short
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
    22
2838
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
    23
# TODO: compat
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
    24
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
    25
if not util.safehasattr(context.basectx, 'orphan'):
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
    26
    context.basectx.orphan = context.basectx.unstable
1c9150e30b28 context: unstable was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2750
diff changeset
    27
2839
f9c8c754a528 context: troubled was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2838
diff changeset
    28
if not util.safehasattr(context.basectx, 'isunstable'):
f9c8c754a528 context: troubled was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2838
diff changeset
    29
    context.basectx.isunstable = context.basectx.troubled
f9c8c754a528 context: troubled was deprecated
Boris Feld <boris.feld@octobus.net>
parents: 2838
diff changeset
    30
3123
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    31
def _stackcandidates(repo):
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    32
    """build the smaller set of revs that might be part of a stack.
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    33
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    34
    The intend is to build something more efficient than what revsets do in
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    35
    this area.
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    36
    """
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    37
    phasecache = repo._phasecache
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    38
    if not phasecache._phasesets:
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    39
        return repo.revs('(not public()) - obsolete()')
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    40
    if any(s is None for s in phasecache._phasesets):
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    41
        return repo.revs('(not public()) - obsolete()')
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    42
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    43
    result = set()
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    44
    for s in phasecache._phasesets[phases.draft:]:
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    45
        result |= s
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    46
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    47
    result -= obsolete.getrevs(repo, 'obsolete')
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    48
    return result
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    49
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    50
class stack(object):
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    51
    """object represent a stack and common logic associated to it."""
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    52
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    53
    def __init__(self, repo, branch=None, topic=None):
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    54
        self._repo = repo
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    55
        self.branch = branch
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    56
        self.topic = topic
2939
7759d040d48d topic: provide more information when behind count cannot be computed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2938
diff changeset
    57
        self.behinderror = None
3123
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    58
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    59
        subset = _stackcandidates(repo)
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    60
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    61
        if topic is not None and branch is not None:
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    62
            raise error.ProgrammingError('both branch and topic specified (not defined yet)')
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    63
        elif topic is not None:
3123
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    64
            trevs = repo.revs("%ld and topic(%s)", subset, topic)
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    65
        elif branch is not None:
3123
237b39bf7e6b topic: instroduce a fast path when computing stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3085
diff changeset
    66
            trevs = repo.revs("%ld and branch(%s) - topic()", subset, branch)
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    67
        else:
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    68
            raise error.ProgrammingError('neither branch and topic specified (not defined yet)')
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    69
        self._revs = trevs
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    70
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    71
    def __iter__(self):
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    72
        return iter(self.revs)
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    73
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    74
    def __getitem__(self, index):
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    75
        return self.revs[index]
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    76
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    77
    def index(self, item):
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    78
        return self.revs.index(item)
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    79
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
    80
    @util.propertycache
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
    81
    def _dependencies(self):
2919
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    82
        deps, rdeps = builddependencies(self._repo, self._revs)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    83
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    84
        repo = self._repo
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    85
        srcpfunc = repo.changelog.parentrevs
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    86
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    87
        ### post process to skip over possible gaps in the stack
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    88
        #
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    89
        # For example in the following situation, we need to detect that "t3"
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    90
        # indirectly depends on t2.
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    91
        #
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    92
        #  o t3
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    93
        #  |
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    94
        #  o other
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    95
        #  |
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    96
        #  o t2
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    97
        #  |
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    98
        #  o t1
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
    99
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   100
        pmap = {}
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   101
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   102
        def pfuncrev(repo, rev):
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   103
            """a special "parent func" that also consider successors"""
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   104
            parents = pmap.get(rev)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   105
            if parents is None:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   106
                parents = [repo[_singlesuccessor(repo, repo[p])].rev()
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   107
                           for p in srcpfunc(rev) if 0 <= p]
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   108
                pmap[rev] = parents
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   109
            return parents
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   110
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   111
        revs = self._revs
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   112
        stackrevs = set(self._revs)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   113
        for root in [r for r in revs if not deps[r]]:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   114
            seen = set()
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   115
            stack = [root]
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   116
            while stack:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   117
                current = stack.pop()
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   118
                for p in pfuncrev(repo, current):
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   119
                    if p in seen:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   120
                        continue
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   121
                    seen.add(p)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   122
                    if p in stackrevs:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   123
                        rdeps[p].add(root)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   124
                        deps[root].add(p)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   125
                    elif phases.public < repo[p].phase():
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   126
                        # traverse only if we did not found a proper candidate
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   127
                        stack.append(p)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   128
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   129
        return deps, rdeps
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   130
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   131
    @util.propertycache
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
   132
    def revs(self):
2919
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   133
        # some duplication/change from _orderrevs because we use a post
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   134
        # processed dependency graph.
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   135
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   136
        # Step 1: compute relation of revision with each other
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   137
        dependencies, rdependencies = self._dependencies
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   138
        dependencies = dependencies.copy()
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   139
        rdependencies = rdependencies.copy()
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   140
        # Step 2: Build the ordering
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   141
        # Remove the revisions with no dependency(A) and add them to the ordering.
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   142
        # Removing these revisions leads to new revisions with no dependency (the
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   143
        # one depending on A) that we can remove from the dependency graph and add
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   144
        # to the ordering. We progress in a similar fashion until the ordering is
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   145
        # built
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   146
        solvablerevs = [r for r in sorted(dependencies.keys())
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   147
                        if not dependencies[r]]
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   148
        revs = []
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   149
        while solvablerevs:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   150
            rev = solvablerevs.pop()
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   151
            for dependent in rdependencies[rev]:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   152
                dependencies[dependent].remove(rev)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   153
                if not dependencies[dependent]:
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   154
                    solvablerevs.append(dependent)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   155
            del dependencies[rev]
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   156
            revs.append(rev)
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   157
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   158
        revs.extend(sorted(dependencies))
5b514ab2ab4e stack: properly order stack when gaps existing inside it
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2918
diff changeset
   159
        # step 3: add t0
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
   160
        if revs:
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
   161
            pt1 = self._repo[revs[0]].p1()
2938
9872526fc39f topic: show the t0 even if topic is not yet touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2937
diff changeset
   162
        else:
9872526fc39f topic: show the t0 even if topic is not yet touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2937
diff changeset
   163
            pt1 = self._repo['.']
9872526fc39f topic: show the t0 even if topic is not yet touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2937
diff changeset
   164
9872526fc39f topic: show the t0 even if topic is not yet touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2937
diff changeset
   165
        if pt1.obsolete():
9872526fc39f topic: show the t0 even if topic is not yet touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2937
diff changeset
   166
            pt1 = self._repo[_singlesuccessor(self._repo, pt1)]
9872526fc39f topic: show the t0 even if topic is not yet touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2937
diff changeset
   167
        revs.insert(0, pt1.rev())
2914
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
   168
        return revs
9897babc1fb5 stack: introduce a rich stack object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2839
diff changeset
   169
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   170
    @util.propertycache
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   171
    def changesetcount(self):
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   172
        return len(self._revs)
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   173
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   174
    @util.propertycache
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   175
    def troubledcount(self):
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   176
        return len([r for r in self._revs if self._repo[r].isunstable()])
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   177
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   178
    @util.propertycache
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   179
    def heads(self):
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   180
        revs = self.revs[1:]
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   181
        deps, rdeps = self._dependencies
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   182
        return [r for r in revs if not rdeps[r]]
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   183
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   184
    @util.propertycache
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   185
    def behindcount(self):
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   186
        revs = self.revs[1:]
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   187
        deps, rdeps = self._dependencies
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   188
        if revs:
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   189
            minroot = [min(r for r in revs if not deps[r])]
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   190
            try:
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   191
                dest = destutil.destmerge(self._repo, action='rebase',
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   192
                                          sourceset=minroot,
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   193
                                          onheadcheck=False)
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   194
                return len(self._repo.revs("only(%d, %ld)", dest, minroot))
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   195
            except error.NoMergeDestAbort:
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   196
                return 0
2939
7759d040d48d topic: provide more information when behind count cannot be computed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2938
diff changeset
   197
            except error.ManyMergeDestAbort as exc:
7759d040d48d topic: provide more information when behind count cannot be computed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2938
diff changeset
   198
                # XXX we should make it easier for upstream to provide the information
7759d040d48d topic: provide more information when behind count cannot be computed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2938
diff changeset
   199
                self.behinderror = str(exc).split('-', 1)[0].rstrip()
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   200
                return -1
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   201
        return 0
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   202
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   203
    @util.propertycache
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   204
    def branches(self):
2936
3a9303b7b648 topics: show working directory branch when topic is empty
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2919
diff changeset
   205
        branches = sorted(set(self._repo[r].branch() for r in self._revs))
3a9303b7b648 topics: show working directory branch when topic is empty
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2919
diff changeset
   206
        if not branches:
3a9303b7b648 topics: show working directory branch when topic is empty
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2919
diff changeset
   207
            branches = set([self._repo[None].branch()])
3a9303b7b648 topics: show working directory branch when topic is empty
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2919
diff changeset
   208
        return branches
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   209
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   210
def labelsgen(prefix, labelssuffix):
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   211
    """ Takes a label prefix and a list of suffixes. Returns a string of the prefix
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   212
    formatted with each suffix separated with a space.
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   213
    """
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   214
    return ' '.join(prefix % suffix for suffix in labelssuffix)
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   215
2669
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   216
def showstack(ui, repo, branch=None, topic=None, opts=None):
2668
1d2c66dc4ee3 topic: explicitly pass topic as a keyword argument
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2632
diff changeset
   217
    if opts is None:
1d2c66dc4ee3 topic: explicitly pass topic as a keyword argument
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2632
diff changeset
   218
        opts = {}
2627
42abd3bd30ee topics: abort if user wants to show the stack of a non-existent topic
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2626
diff changeset
   219
2669
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   220
    if topic is not None and branch is not None:
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   221
        msg = 'both branch and topic specified [%s]{%s}(not defined yet)'
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   222
        msg %= (branch, topic)
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   223
        raise error.ProgrammingError(msg)
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   224
    elif topic is not None:
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   225
        prefix = 't'
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   226
        if topic not in repo.topics:
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   227
            raise error.Abort(_('cannot resolve "%s": no such topic found') % topic)
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   228
    elif branch is not None:
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   229
        prefix = 'b'
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   230
    else:
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   231
        raise error.ProgrammingError('neither branch and topic specified (not defined yet)')
2627
42abd3bd30ee topics: abort if user wants to show the stack of a non-existent topic
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2626
diff changeset
   232
1907
95874e8fc5f2 stack: add basic formatter and label support
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1906
diff changeset
   233
    fm = ui.formatter('topicstack', opts)
1909
36112e361ee4 stack: display the base of the stack
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1907
diff changeset
   234
    prev = None
1955
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   235
    entries = []
1991
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   236
    idxmap = {}
1995
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
   237
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
   238
    label = 'topic'
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
   239
    if topic == repo.currenttopic:
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
   240
        label = 'topic.active'
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
   241
2669
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   242
    data = stackdata(repo, branch=branch, topic=topic)
2937
b54abc7e80e2 topics: improve the description if topic is not touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2936
diff changeset
   243
    empty = False
b54abc7e80e2 topics: improve the description if topic is not touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2936
diff changeset
   244
    if data['changesetcount'] == 0:
b54abc7e80e2 topics: improve the description if topic is not touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2936
diff changeset
   245
        empty = True
2670
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   246
    if topic is not None:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   247
        fm.plain(_('### topic: %s')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   248
                 % ui.label(topic, label),
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   249
                 label='topic.stack.summary.topic')
1998
302be26a3fd8 stack: add warning about multiple heads
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1997
diff changeset
   250
2670
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   251
        if 1 < data['headcount']:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   252
            fm.plain(' (')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   253
            fm.plain('%d heads' % data['headcount'],
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   254
                     label='topic.stack.summary.headcount.multiple')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   255
            fm.plain(')')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   256
        fm.plain('\n')
2997
a61634f52742 topic: try to clarify the "branch" part in stack
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2939
diff changeset
   257
    fm.plain(_('### target: %s (branch)')
1996
5c40dd2cf131 stack: add some basic branch information
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1995
diff changeset
   258
             % '+'.join(data['branches']), # XXX handle multi branches
5c40dd2cf131 stack: add some basic branch information
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1995
diff changeset
   259
             label='topic.stack.summary.branches')
2670
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   260
    if topic is None:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   261
        if 1 < data['headcount']:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   262
            fm.plain(' (')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   263
            fm.plain('%d heads' % data['headcount'],
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   264
                     label='topic.stack.summary.headcount.multiple')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   265
            fm.plain(')')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   266
    else:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   267
        if data['behindcount'] == -1:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   268
            fm.plain(', ')
3228
8cc8fb94cc00 typos: fix typos in several locations
Kyle Lippincott <spectral@google.com>
parents: 3123
diff changeset
   269
            fm.plain('ambiguous rebase destination - %s' % data['behinderror'],
2939
7759d040d48d topic: provide more information when behind count cannot be computed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2938
diff changeset
   270
                     label='topic.stack.summary.behinderror')
2670
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   271
        elif data['behindcount']:
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   272
            fm.plain(', ')
f5d52fa1cd55 topic: move the heads data to the branch line when appropriates
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2669
diff changeset
   273
            fm.plain('%d behind' % data['behindcount'], label='topic.stack.summary.behindcount')
1997
ce86f7bb4b7b stack: add some behind information
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1996
diff changeset
   274
    fm.plain('\n')
1995
54d6dff699f0 stack: add some header with the topic name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1991
diff changeset
   275
2937
b54abc7e80e2 topics: improve the description if topic is not touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2936
diff changeset
   276
    if empty:
b54abc7e80e2 topics: improve the description if topic is not touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2936
diff changeset
   277
        fm.plain(_("(stack is empty)\n"))
b54abc7e80e2 topics: improve the description if topic is not touched
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2936
diff changeset
   278
2915
b3abdb3d819e stack: replace 'getstack' with direct call to 'stack'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2914
diff changeset
   279
    for idx, r in enumerate(stack(repo, branch=branch, topic=topic), 0):
1925
8f8a48a2e97d stack: whitespace
Sean Farley <sean@farley.io>
parents: 1924
diff changeset
   280
        ctx = repo[r]
2712
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   281
        # special case for t0, b0 as it's hard to plugin into rest of the logic
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   282
        if idx == 0:
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   283
            # t0, b0 can be None
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   284
            if r == -1:
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   285
                continue
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   286
            entries.append((idx, False, ctx))
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   287
            prev = ctx.rev()
f19b314d8475 topics: add t0 and b0 to the stack
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2684
diff changeset
   288
            continue
1909
36112e361ee4 stack: display the base of the stack
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1907
diff changeset
   289
        p1 = ctx.p1()
2918
0437158e0ed6 stack: display both parent with displaying merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2916
diff changeset
   290
        p2 = ctx.p2()
1909
36112e361ee4 stack: display the base of the stack
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1907
diff changeset
   291
        if p1.obsolete():
3278
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   292
            try:
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   293
                p1 = repo[_singlesuccessor(repo, p1)]
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   294
            except MultipleSuccessorsError as e:
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   295
                successors = e.successorssets
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   296
                if len(successors) > 1:
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   297
                    # case of divergence which we don't handle yet
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   298
                    raise
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   299
                p1 = repo[successors[0][-1]]
e4c0332ecee4 topics: fix `hg stack` in case of split
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3228
diff changeset
   300
2918
0437158e0ed6 stack: display both parent with displaying merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2916
diff changeset
   301
        if p2.node() != node.nullid:
0437158e0ed6 stack: display both parent with displaying merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2916
diff changeset
   302
            entries.append((idxmap.get(p1.rev()), False, p1))
0437158e0ed6 stack: display both parent with displaying merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2916
diff changeset
   303
            entries.append((idxmap.get(p2.rev()), False, p2))
0437158e0ed6 stack: display both parent with displaying merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2916
diff changeset
   304
        elif p1.rev() != prev and p1.node() != node.nullid:
1991
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   305
            entries.append((idxmap.get(p1.rev()), False, p1))
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   306
        entries.append((idx, True, ctx))
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   307
        idxmap[ctx.rev()] = idx
1955
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   308
        prev = r
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   309
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   310
    # super crude initial version
1991
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   311
    for idx, isentry, ctx in entries[::-1]:
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   312
3084
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   313
        symbol = None
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   314
        states = []
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   315
        iscurrentrevision = repo.revs('%d and parents()', ctx.rev())
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   316
3084
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   317
        if iscurrentrevision:
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   318
            states.append('current')
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   319
            symbol = '@'
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   320
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   321
        if ctx.orphan():
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   322
            symbol = '$'
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   323
            states.append('unstable')
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   324
1991
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   325
        if not isentry:
1957
ea5553e47027 stack: change the ascii symbold for base
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1956
diff changeset
   326
            symbol = '^'
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   327
            # "base" is kind of a "ghost" entry
3084
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   328
            states.append('base')
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   329
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   330
        # none of the above if statments get executed
144989dabe93 stack: show current and unstable also for t0 and bases
Pulkit Goyal <7895pulkit@gmail.com>
parents: 3061
diff changeset
   331
        if not symbol:
1955
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   332
            symbol = ':'
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   333
            states.append('clean')
3085
3eca2cbdc498 stack: order the adjective of changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3084
diff changeset
   334
3eca2cbdc498 stack: order the adjective of changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3084
diff changeset
   335
        states.sort()
3eca2cbdc498 stack: order the adjective of changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3084
diff changeset
   336
1907
95874e8fc5f2 stack: add basic formatter and label support
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1906
diff changeset
   337
        fm.startitem()
1991
ba79d23594d6 stack: reusing the index number in base when applicable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1990
diff changeset
   338
        fm.data(isentry=isentry)
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   339
1955
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   340
        if idx is None:
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   341
            fm.plain('  ')
2750
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
   342
            if ui.verbose:
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
   343
                fm.plain('              ')
1955
5452a575b4e5 topic: extract display from entry computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1954
diff changeset
   344
        else:
2669
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   345
            fm.write('topic.stack.index', '%s%%d' % prefix, idx,
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   346
                     label='topic.stack.index ' + labelsgen('topic.stack.index.%s', states))
2750
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
   347
            if ui.verbose:
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
   348
                fm.write('topic.stack.shortnode', '(%s)', short(ctx.node()),
bd3824d1b795 stack: show short node of changesets in `hg stack -v`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 2712
diff changeset
   349
                         label='topic.stack.shortnode ' + labelsgen('topic.stack.shortnode.%s', states))
1907
95874e8fc5f2 stack: add basic formatter and label support
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1906
diff changeset
   350
        fm.write('topic.stack.state.symbol', '%s', symbol,
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   351
                 label='topic.stack.state ' + labelsgen('topic.stack.state.%s', states))
1907
95874e8fc5f2 stack: add basic formatter and label support
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1906
diff changeset
   352
        fm.plain(' ')
1909
36112e361ee4 stack: display the base of the stack
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1907
diff changeset
   353
        fm.write('topic.stack.desc', '%s', ctx.description().splitlines()[0],
2348
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   354
                 label='topic.stack.desc ' + labelsgen('topic.stack.desc.%s', states))
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   355
        fm.condwrite(states != ['clean'] and idx is not None, 'topic.stack.state',
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   356
                     ' (%s)', fm.formatlist(states, 'topic.stack.state'),
5737e0680f10 ui: hg topic now display if current revision is in bad state (issue5533)
Boris Feld <boris.feld@octobus.net>
parents: 2341
diff changeset
   357
                     label='topic.stack.state ' + labelsgen('topic.stack.state.%s', states))
1907
95874e8fc5f2 stack: add basic formatter and label support
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1906
diff changeset
   358
        fm.plain('\n')
2341
a5117a5becf8 ui: Fix hg stack json output
Boris Feld <boris.feld@octobus.net>
parents: 2003
diff changeset
   359
    fm.end()
1897
38570c53b1cf stack: fix printing order in case of unstability
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 1896
diff changeset
   360
2669
b933a8068c17 topic: add some initial support for using stack on named branch
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2668
diff changeset
   361
def stackdata(repo, branch=None, topic=None):
1977
137f8b04901e topic: list the number of changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1961
diff changeset
   362
    """get various data about a stack
137f8b04901e topic: list the number of changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1961
diff changeset
   363
137f8b04901e topic: list the number of changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1961
diff changeset
   364
    :changesetcount: number of non-obsolete changesets in the stack
1978
e42dd4523c0d topic: list the number of troubled changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1977
diff changeset
   365
    :troubledcount: number on troubled changesets
1979
bee7a1ef8ba8 topic: list the number of head when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1978
diff changeset
   366
    :headcount: number of heads on the topic
1985
03d6b685c16a topic: list the number of 'behind' changeset when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1982
diff changeset
   367
    :behindcount: number of changeset on rebase destination
1977
137f8b04901e topic: list the number of changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1961
diff changeset
   368
    """
137f8b04901e topic: list the number of changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1961
diff changeset
   369
    data = {}
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   370
    current = stack(repo, branch, topic)
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   371
    data['changesetcount'] = current.changesetcount
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   372
    data['troubledcount'] = current.troubledcount
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   373
    data['headcount'] = len(current.heads)
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   374
    data['behindcount'] = current.behindcount
2939
7759d040d48d topic: provide more information when behind count cannot be computed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2938
diff changeset
   375
    data['behinderror'] = current.behinderror
2916
17749d9d3968 stack: move data computation on the object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2915
diff changeset
   376
    data['branches'] = current.branches
1977
137f8b04901e topic: list the number of changesets when --verbose is used
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1961
diff changeset
   377
    return data