stack: reusing the index number in base when applicable
This clarify the branching when it is easy to track back the branching point.
This does not takes the evolution graph into account yet.
# stack.py - code related to stack workflow
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from mercurial import (
destutil,
error,
node,
)
from .evolvebits import builddependencies, _orderrevs, _singlesuccessor
def getstack(repo, topic):
# XXX need sorting
trevs = repo.revs("topic(%s) - obsolete()", topic)
return _orderrevs(repo, trevs)
def showstack(ui, repo, topic, opts):
fm = ui.formatter('topicstack', opts)
prev = None
entries = []
idxmap = {}
for idx, r in enumerate(getstack(repo, topic), 1):
ctx = repo[r]
p1 = ctx.p1()
if p1.obsolete():
p1 = repo[_singlesuccessor(repo, p1)]
if p1.rev() != prev and p1.node() != node.nullid:
entries.append((idxmap.get(p1.rev()), False, p1))
entries.append((idx, True, ctx))
idxmap[ctx.rev()] = idx
prev = r
# super crude initial version
for idx, isentry, ctx in entries[::-1]:
if not isentry:
symbol = '^'
state = 'base'
elif repo.revs('%d and parents()', ctx.rev()):
symbol = '@'
state = 'current'
elif repo.revs('%d and unstable()', ctx.rev()):
symbol = '$'
state = 'unstable'
else:
symbol = ':'
state = 'clean'
fm.startitem()
fm.data(isentry=isentry)
if idx is None:
fm.plain(' ')
else:
fm.write('topic.stack.index', 't%d', idx,
label='topic.stack.index topic.stack.index.%s' % state)
fm.write('topic.stack.state.symbol', '%s', symbol,
label='topic.stack.state topic.stack.state.%s' % state)
fm.plain(' ')
fm.write('topic.stack.desc', '%s', ctx.description().splitlines()[0],
label='topic.stack.desc topic.stack.desc.%s' % state)
fm.condwrite(state != 'clean' and idx is not None, 'topic.stack.state',
' (%s)', state,
label='topic.stack.state topic.stack.state.%s' % state)
fm.plain('\n')
fm.end()
def stackdata(repo, topic):
"""get various data about a stack
:changesetcount: number of non-obsolete changesets in the stack
:troubledcount: number on troubled changesets
:headcount: number of heads on the topic
:behindcount: number of changeset on rebase destination
"""
data = {}
revs = repo.revs("topic(%s) - obsolete()", topic)
data['changesetcount'] = len(revs)
data['troubledcount'] = len([r for r in revs if repo[r].troubled()])
deps, rdeps = builddependencies(repo, revs)
data['headcount'] = len([r for r in revs if not rdeps[r]])
data['behindcount'] = 0
if revs:
minroot = [min(r for r in revs if not deps[r])]
try:
dest = destutil.destmerge(repo, action='rebase',
sourceset=minroot,
onheadcheck=False)
data['behindcount'] = len(repo.revs("only(%d, %ld)", dest,
minroot))
except error.NoMergeDestAbort:
data['behindcount'] = 0
except error.ManyMergeDestAbort:
data['behindcount'] = -1
data['branches'] = sorted(set(repo[r].branch() for r in revs))
return data