mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 01:07:15 +03:00
f260c80298
Upstream has added devel warnings that require us to register all the configs and remove the defaults that are specified at read time. This doesn't fix all the cases, but is the start. Differential Revision: https://phab.mercurial-scm.org/D1206
171 lines
5.6 KiB
Python
171 lines
5.6 KiB
Python
# morestatus.py
|
|
#
|
|
# Copyright 2015 Facebook, Inc.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2 or any later version.
|
|
"""make status give a bit more context
|
|
|
|
This extension will wrap the status command to make it show more context about
|
|
the state of the repo
|
|
"""
|
|
|
|
import os
|
|
from mercurial import commands
|
|
from mercurial.extensions import wrapcommand
|
|
from mercurial.i18n import _
|
|
from mercurial import merge as mergemod
|
|
from mercurial import scmutil
|
|
|
|
from mercurial import (
|
|
registrar,
|
|
)
|
|
|
|
UPDATEARGS = 'updateargs'
|
|
|
|
configtable = {}
|
|
configitem = registrar.configitem(configtable)
|
|
|
|
configitem('morestatus', 'show', default=False)
|
|
|
|
def prefixlines(raw):
|
|
'''Surround lineswith a comment char and a new line'''
|
|
lines = raw.splitlines()
|
|
commentedlines = ['# %s' % line for line in lines]
|
|
return '\n'.join(commentedlines) + '\n'
|
|
|
|
|
|
def conflictsmsg(repo, ui):
|
|
mergestate = mergemod.mergestate.read(repo)
|
|
if not mergestate.active():
|
|
return
|
|
|
|
m = scmutil.match(repo[None])
|
|
unresolvedlist = [f for f in mergestate if m(f) and mergestate[f] == 'u']
|
|
if unresolvedlist:
|
|
mergeliststr = '\n'.join(
|
|
[' %s' % os.path.relpath(
|
|
os.path.join(repo.root, path),
|
|
os.getcwd()) for path in unresolvedlist])
|
|
msg = _('''Unresolved merge conflicts:
|
|
|
|
%s
|
|
|
|
To mark files as resolved: hg resolve --mark FILE''') % mergeliststr
|
|
else:
|
|
msg = _('No unresolved merge conflicts.')
|
|
|
|
ui.warn(prefixlines(msg))
|
|
|
|
def helpmessage(ui, continuecmd, abortcmd):
|
|
msg = _('To continue: %s\n'
|
|
'To abort: %s') % (continuecmd, abortcmd)
|
|
ui.warn(prefixlines(msg))
|
|
|
|
def rebasemsg(repo, ui):
|
|
helpmessage(ui, 'hg rebase --continue', 'hg rebase --abort')
|
|
|
|
def histeditmsg(repo, ui):
|
|
helpmessage(ui, 'hg histedit --continue', 'hg histedit --abort')
|
|
|
|
def unshelvemsg(repo, ui):
|
|
helpmessage(ui, 'hg unshelve --continue', 'hg unshelve --abort')
|
|
|
|
def updatecleanmsg(dest=None):
|
|
warning = _('warning: this will discard uncommitted changes')
|
|
return 'hg update --clean %s (%s)' % (dest or '.', warning)
|
|
|
|
def graftmsg(repo, ui):
|
|
# tweakdefaults requires `update` to have a rev hence the `.`
|
|
helpmessage(ui, 'hg graft --continue', updatecleanmsg())
|
|
|
|
def updatemsg(repo, ui):
|
|
previousargs = repo.vfs.tryread(UPDATEARGS)
|
|
if previousargs:
|
|
continuecmd = 'hg ' + previousargs
|
|
else:
|
|
continuecmd = 'hg update ' + repo.vfs.read('updatestate')[:12]
|
|
abortcmd = updatecleanmsg(repo._activebookmark)
|
|
helpmessage(ui, continuecmd, abortcmd)
|
|
|
|
def mergemsg(repo, ui):
|
|
# tweakdefaults requires `update` to have a rev hence the `.`
|
|
helpmessage(ui, 'hg commit', updatecleanmsg())
|
|
|
|
def bisectmsg(repo, ui):
|
|
msg = _('To mark the changeset good: hg bisect --good\n'
|
|
'To mark the changeset bad: hg bisect --bad\n'
|
|
'To abort: hg bisect --reset\n')
|
|
ui.warn(prefixlines(msg))
|
|
|
|
def fileexistspredicate(filename):
|
|
return lambda repo: repo.vfs.exists(filename)
|
|
|
|
def mergepredicate(repo):
|
|
return len(repo[None].parents()) > 1
|
|
|
|
STATES = (
|
|
# (state, predicate to detect states, helpful message function)
|
|
('histedit', fileexistspredicate('histedit-state'), histeditmsg),
|
|
('bisect', fileexistspredicate('bisect.state'), bisectmsg),
|
|
('graft', fileexistspredicate('graftstate'), graftmsg),
|
|
('unshelve', fileexistspredicate('unshelverebasestate'), unshelvemsg),
|
|
('rebase', fileexistspredicate('rebasestate'), rebasemsg),
|
|
# The merge and update states are part of a list that will be iterated over.
|
|
# They need to be last because some of the other unfinished states may also
|
|
# be in a merge or update state (eg. rebase, histedit, graft, etc).
|
|
# We want those to have priority.
|
|
('merge', mergepredicate, mergemsg),
|
|
('update', fileexistspredicate('updatestate'), updatemsg),
|
|
)
|
|
|
|
|
|
def extsetup(ui):
|
|
if ui.configbool('morestatus', 'show') and not ui.plain():
|
|
wrapcommand(commands.table, 'status', statuscmd)
|
|
# Write down `hg update` args to show the continue command in
|
|
# interrupted update state.
|
|
ui.setconfig('hooks', 'pre-update.morestatus', saveupdateargs)
|
|
ui.setconfig('hooks', 'post-update.morestatus', cleanupdateargs)
|
|
|
|
def saveupdateargs(repo, args, **kwargs):
|
|
# args is a string containing all flags and arguments
|
|
with repo.wlock():
|
|
repo.vfs.write(UPDATEARGS, args)
|
|
|
|
def cleanupdateargs(repo, **kwargs):
|
|
with repo.wlock():
|
|
repo.vfs.tryunlink(UPDATEARGS)
|
|
|
|
def statuscmd(orig, ui, repo, *pats, **opts):
|
|
"""
|
|
Wrap the status command to barf out the state of the repository. States
|
|
being mid histediting, mid bisecting, grafting, merging, etc.
|
|
Output is to stderr to avoid breaking scripts.
|
|
"""
|
|
|
|
ret = orig(ui, repo, *pats, **opts)
|
|
|
|
statetuple = getrepostate(repo)
|
|
if statetuple:
|
|
state, statedetectionpredicate, helpfulmsg = statetuple
|
|
statemsg = _('The repository is in an unfinished *%s* state.') % state
|
|
ui.warn('\n' + prefixlines(statemsg))
|
|
conflictsmsg(repo, ui)
|
|
if helpfulmsg:
|
|
helpfulmsg(repo, ui)
|
|
|
|
# TODO(cdelahousse): check to see if current bookmark needs updating. See
|
|
# scmprompt.
|
|
|
|
return ret
|
|
|
|
def getrepostate(repo):
|
|
# experimental config: morestatus.skipstates
|
|
skip = set(repo.ui.configlist('morestatus', 'skipstates', []))
|
|
for state, statedetectionpredicate, msgfn in STATES:
|
|
if state in skip:
|
|
continue
|
|
if statedetectionpredicate(repo):
|
|
return (state, statedetectionpredicate, msgfn)
|