Mercurial > public > mercurial-scm > hg-stable
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. |