comparison mercurial/cmdutil.py @ 33792:96f43981c1c4

morestatus: move fb extension to core by plugging to `hg status --verbose` morestatus extension in fbext use to show more context about the state of the repo like the repository is in a unfinished merge state, or a rebase is going on, or histedit is going on, listing the files which need to be resolved and also suggesting ways to handle the situation. This patch moves the extension directly to core by plugging it into the --verbose flag of the status command. So now if you are in any unfinished state and you do hg status -v, it will show you details and help related to the state. The extension in fbext also shows context about unfinished update state which is not ported to core as that plug in hooks to update command which need to be tackled somewhat differently. The following configuration will turn the behaviour on by default [commands] status.verbose = 1 You can also skip considering some states like bisect as follows: [commands] status.skipstates=bisect This patch also adds test for the feature. .. feature:: ``hg status -v`` can now show unfinished state. For example, when in an unfinished rebase state, ``hg status -v`` might show:: # The repository is in an unfinished *rebase* state. # No unresolved merge conflicts. # To continue: hg rebase --continue # To abort: hg rebase --abort Differential Revision: https://phab.mercurial-scm.org/D219
author Pulkit Goyal <7895pulkit@gmail.com>
date Thu, 03 Aug 2017 05:12:35 +0530
parents 02a745c20121
children 3821dfee2cfc
comparison
equal deleted inserted replaced
33791:119e1c6be1ce 33792:96f43981c1c4
570 for x in xrange(len(indexes)): 570 for x in xrange(len(indexes)):
571 if not finalrs[x]: 571 if not finalrs[x]:
572 finalrs[x] = statlist[x] 572 finalrs[x] = statlist[x]
573 573
574 return finalrs 574 return finalrs
575
576 def _commentlines(raw):
577 '''Surround lineswith a comment char and a new line'''
578 lines = raw.splitlines()
579 commentedlines = ['# %s' % line for line in lines]
580 return '\n'.join(commentedlines) + '\n'
581
582 def _conflictsmsg(repo):
583 # avoid merge cycle
584 from . import merge as mergemod
585 mergestate = mergemod.mergestate.read(repo)
586 if not mergestate.active():
587 return
588
589 m = scmutil.match(repo[None])
590 unresolvedlist = [f for f in mergestate if m(f) and mergestate[f] == 'u']
591 if unresolvedlist:
592 mergeliststr = '\n'.join(
593 [' %s' % os.path.relpath(
594 os.path.join(repo.root, path),
595 pycompat.getcwd()) for path in unresolvedlist])
596 msg = _('''Unresolved merge conflicts:
597
598 %s
599
600 To mark files as resolved: hg resolve --mark FILE''') % mergeliststr
601 else:
602 msg = _('No unresolved merge conflicts.')
603
604 return _commentlines(msg)
605
606 def _helpmessage(continuecmd, abortcmd):
607 msg = _('To continue: %s\n'
608 'To abort: %s') % (continuecmd, abortcmd)
609 return _commentlines(msg)
610
611 def _rebasemsg():
612 return _helpmessage('hg rebase --continue', 'hg rebase --abort')
613
614 def _histeditmsg():
615 return _helpmessage('hg histedit --continue', 'hg histedit --abort')
616
617 def _unshelvemsg():
618 return _helpmessage('hg unshelve --continue', 'hg unshelve --abort')
619
620 def _updatecleanmsg(dest=None):
621 warning = _('warning: this will discard uncommitted changes')
622 return 'hg update --clean %s (%s)' % (dest or '.', warning)
623
624 def _graftmsg():
625 # tweakdefaults requires `update` to have a rev hence the `.`
626 return _helpmessage('hg graft --continue', _updatecleanmsg())
627
628 def _mergemsg():
629 # tweakdefaults requires `update` to have a rev hence the `.`
630 return _helpmessage('hg commit', _updatecleanmsg())
631
632 def _bisectmsg():
633 msg = _('To mark the changeset good: hg bisect --good\n'
634 'To mark the changeset bad: hg bisect --bad\n'
635 'To abort: hg bisect --reset\n')
636 return _commentlines(msg)
637
638 def fileexistspredicate(filename):
639 return lambda repo: repo.vfs.exists(filename)
640
641 def _mergepredicate(repo):
642 return len(repo[None].parents()) > 1
643
644 STATES = (
645 # (state, predicate to detect states, helpful message function)
646 ('histedit', fileexistspredicate('histedit-state'), _histeditmsg),
647 ('bisect', fileexistspredicate('bisect.state'), _bisectmsg),
648 ('graft', fileexistspredicate('graftstate'), _graftmsg),
649 ('unshelve', fileexistspredicate('unshelverebasestate'), _unshelvemsg),
650 ('rebase', fileexistspredicate('rebasestate'), _rebasemsg),
651 # The merge state is part of a list that will be iterated over.
652 # They need to be last because some of the other unfinished states may also
653 # be in a merge or update state (eg. rebase, histedit, graft, etc).
654 # We want those to have priority.
655 ('merge', _mergepredicate, _mergemsg),
656 )
657
658 def _getrepostate(repo):
659 # experimental config: commands.status.skipstates
660 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
661 for state, statedetectionpredicate, msgfn in STATES:
662 if state in skip:
663 continue
664 if statedetectionpredicate(repo):
665 return (state, statedetectionpredicate, msgfn)
666
667 def morestatus(repo, fm):
668 statetuple = _getrepostate(repo)
669 label = 'status.morestatus'
670 if statetuple:
671 fm.startitem()
672 state, statedetectionpredicate, helpfulmsg = statetuple
673 statemsg = _('The repository is in an unfinished *%s* state.') % state
674 fm.write('statemsg', '%s\n', _commentlines(statemsg), label=label)
675 conmsg = _conflictsmsg(repo)
676 fm.write('conflictsmsg', '%s\n', conmsg, label=label)
677 if helpfulmsg:
678 helpmsg = helpfulmsg()
679 fm.write('helpmsg', '%s\n', helpmsg, label=label)
575 680
576 def findpossible(cmd, table, strict=False): 681 def findpossible(cmd, table, strict=False):
577 """ 682 """
578 Return cmd -> (aliases, command table entry) 683 Return cmd -> (aliases, command table entry)
579 for each matching command. 684 for each matching command.