Mercurial > hg
comparison hgext/histedit.py @ 27675:d073f4c70575
histedit: replace @addhisteditaction with @action
@action supports verbs, messages, priority, and internal
messages should be translated.
internal means the action should not be listed.
geteditcomment will construct the verbs list based on
@actions (prefering priority over non priority, otherwise
favoring verbs with short forms over verbs without).
author | timeless <timeless@mozdev.org> |
---|---|
date | Wed, 23 Dec 2015 21:30:38 +0000 |
parents | 78d86664e3a2 |
children | bb810c8b3eca |
comparison
equal
deleted
inserted
replaced
27674:78d86664e3a2 | 27675:d073f4c70575 |
---|---|
212 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | 212 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
213 # be specifying the version(s) of Mercurial they are tested with, or | 213 # be specifying the version(s) of Mercurial they are tested with, or |
214 # leave the attribute unspecified. | 214 # leave the attribute unspecified. |
215 testedwith = 'internal' | 215 testedwith = 'internal' |
216 | 216 |
217 actiontable = {} | |
218 primaryactions = set() | |
219 secondaryactions = set() | |
220 tertiaryactions = set() | |
221 internalactions = set() | |
222 | |
217 def geteditcomment(first, last): | 223 def geteditcomment(first, last): |
218 """ construct the editor comment | 224 """ construct the editor comment |
219 The comment includes:: | 225 The comment includes:: |
220 - an intro | 226 - an intro |
221 - sorted primary commands | 227 - sorted primary commands |
222 - sorted short commands | 228 - sorted short commands |
229 - sorted long commands | |
223 | 230 |
224 Commands are only included once. | 231 Commands are only included once. |
225 """ | 232 """ |
226 intro = _("""Edit history between %s and %s | 233 intro = _("""Edit history between %s and %s |
227 | 234 |
228 Commits are listed from least to most recent | 235 Commits are listed from least to most recent |
229 | 236 |
230 Commands:""") | 237 Commands: |
231 # i18n: command names and abbreviations must remain untranslated | |
232 verbs = _(""" | |
233 e, edit = use commit, but stop for amending | |
234 m, mess = edit commit message without changing commit content | |
235 p, pick = use commit | |
236 d, drop = remove commit from history | |
237 f, fold = use commit, but combine it with the one above | |
238 r, roll = like fold, but discard this commit's description | |
239 """) | 238 """) |
239 actions = [] | |
240 def addverb(v): | |
241 a = actiontable[v] | |
242 lines = a.message.split("\n") | |
243 if len(a.verbs): | |
244 v = ', '.join(sorted(a.verbs, key=lambda v: len(v))) | |
245 actions.append(" %s = %s" % (v, lines[0])) | |
246 actions.extend([' %s' for l in lines[1:]]) | |
247 | |
248 for v in ( | |
249 sorted(primaryactions) + | |
250 sorted(secondaryactions) + | |
251 sorted(tertiaryactions) | |
252 ): | |
253 addverb(v) | |
254 actions.append('') | |
240 | 255 |
241 return ''.join(['# %s\n' % l if l else '#\n' | 256 return ''.join(['# %s\n' % l if l else '#\n' |
242 for l in ((intro % (first, last) + verbs).split('\n'))]) | 257 for l in ((intro % (first, last)).split('\n')) + actions]) |
243 | 258 |
244 class histeditstate(object): | 259 class histeditstate(object): |
245 def __init__(self, repo, parentctxnode=None, actions=None, keep=None, | 260 def __init__(self, repo, parentctxnode=None, actions=None, keep=None, |
246 topmost=None, replacements=None, lock=None, wlock=None): | 261 topmost=None, replacements=None, lock=None, wlock=None): |
247 self.repo = repo | 262 self.repo = repo |
596 def abortdirty(): | 611 def abortdirty(): |
597 raise error.Abort(_('working copy has pending changes'), | 612 raise error.Abort(_('working copy has pending changes'), |
598 hint=_('amend, commit, or revert them and run histedit ' | 613 hint=_('amend, commit, or revert them and run histedit ' |
599 '--continue, or abort with histedit --abort')) | 614 '--continue, or abort with histedit --abort')) |
600 | 615 |
601 | 616 def action(verbs, message, priority=False, internal=False): |
602 actiontable = {} | |
603 actionlist = [] | |
604 | |
605 def addhisteditaction(verbs): | |
606 def wrap(cls): | 617 def wrap(cls): |
607 cls.verb = verbs[0] | 618 assert not priority or not internal |
619 verb = verbs[0] | |
620 if priority: | |
621 primaryactions.add(verb) | |
622 elif internal: | |
623 internalactions.add(verb) | |
624 elif len(verbs) > 1: | |
625 secondaryactions.add(verb) | |
626 else: | |
627 tertiaryactions.add(verb) | |
628 | |
629 cls.verb = verb | |
630 cls.verbs = verbs | |
631 cls.message = message | |
608 for verb in verbs: | 632 for verb in verbs: |
609 actiontable[verb] = cls | 633 actiontable[verb] = cls |
610 actionlist.append(cls) | |
611 return cls | 634 return cls |
612 return wrap | 635 return wrap |
613 | 636 |
614 | 637 @action(['pick', 'p'], |
615 @addhisteditaction(['pick', 'p']) | 638 _('use commit'), |
639 priority=True) | |
616 class pick(histeditaction): | 640 class pick(histeditaction): |
617 def run(self): | 641 def run(self): |
618 rulectx = self.repo[self.node] | 642 rulectx = self.repo[self.node] |
619 if rulectx.parents()[0].node() == self.state.parentctxnode: | 643 if rulectx.parents()[0].node() == self.state.parentctxnode: |
620 self.repo.ui.debug('node %s unchanged\n' % node.short(self.node)) | 644 self.repo.ui.debug('node %s unchanged\n' % node.short(self.node)) |
621 return rulectx, [] | 645 return rulectx, [] |
622 | 646 |
623 return super(pick, self).run() | 647 return super(pick, self).run() |
624 | 648 |
625 @addhisteditaction(['edit', 'e']) | 649 @action(['edit', 'e'], |
650 _('use commit, but stop for amending'), | |
651 priority=True) | |
626 class edit(histeditaction): | 652 class edit(histeditaction): |
627 def run(self): | 653 def run(self): |
628 repo = self.repo | 654 repo = self.repo |
629 rulectx = repo[self.node] | 655 rulectx = repo[self.node] |
630 hg.update(repo, self.state.parentctxnode, quietempty=True) | 656 hg.update(repo, self.state.parentctxnode, quietempty=True) |
635 hint=_('hg histedit --continue to resume')) | 661 hint=_('hg histedit --continue to resume')) |
636 | 662 |
637 def commiteditor(self): | 663 def commiteditor(self): |
638 return cmdutil.getcommiteditor(edit=True, editform='histedit.edit') | 664 return cmdutil.getcommiteditor(edit=True, editform='histedit.edit') |
639 | 665 |
640 @addhisteditaction(['fold', 'f']) | 666 @action(['fold', 'f'], |
667 _('use commit, but combine it with the one above')) | |
641 class fold(histeditaction): | 668 class fold(histeditaction): |
642 def verify(self, prev): | 669 def verify(self, prev): |
643 """ Verifies semantic correctness of the fold rule""" | 670 """ Verifies semantic correctness of the fold rule""" |
644 super(fold, self).verify(prev) | 671 super(fold, self).verify(prev) |
645 repo = self.repo | 672 repo = self.repo |
761 | 788 |
762 def continueclean(self): | 789 def continueclean(self): |
763 basectx = self.repo['.'] | 790 basectx = self.repo['.'] |
764 return basectx, [] | 791 return basectx, [] |
765 | 792 |
766 @addhisteditaction(['_multifold']) | 793 @action(['_multifold'], |
767 class _multifold(fold): | 794 _( |
768 """fold subclass used for when multiple folds happen in a row | 795 """fold subclass used for when multiple folds happen in a row |
769 | 796 |
770 We only want to fire the editor for the folded message once when | 797 We only want to fire the editor for the folded message once when |
771 (say) four changes are folded down into a single change. This is | 798 (say) four changes are folded down into a single change. This is |
772 similar to rollup, but we should preserve both messages so that | 799 similar to rollup, but we should preserve both messages so that |
773 when the last fold operation runs we can show the user all the | 800 when the last fold operation runs we can show the user all the |
774 commit messages in their editor. | 801 commit messages in their editor. |
775 """ | 802 """), |
803 internal=True) | |
804 class _multifold(fold): | |
776 def skipprompt(self): | 805 def skipprompt(self): |
777 return True | 806 return True |
778 | 807 |
779 @addhisteditaction(["roll", "r"]) | 808 @action(["roll", "r"], |
809 _("like fold, but discard this commit's description")) | |
780 class rollup(fold): | 810 class rollup(fold): |
781 def mergedescs(self): | 811 def mergedescs(self): |
782 return False | 812 return False |
783 | 813 |
784 def skipprompt(self): | 814 def skipprompt(self): |
785 return True | 815 return True |
786 | 816 |
787 @addhisteditaction(["drop", "d"]) | 817 @action(["drop", "d"], |
818 _('remove commit from history')) | |
788 class drop(histeditaction): | 819 class drop(histeditaction): |
789 def run(self): | 820 def run(self): |
790 parentctx = self.repo[self.state.parentctxnode] | 821 parentctx = self.repo[self.state.parentctxnode] |
791 return parentctx, [(self.node, tuple())] | 822 return parentctx, [(self.node, tuple())] |
792 | 823 |
793 @addhisteditaction(["mess", "m"]) | 824 @action(["mess", "m"], |
825 _('edit commit message without changing commit content'), | |
826 priority=True) | |
794 class message(histeditaction): | 827 class message(histeditaction): |
795 def commiteditor(self): | 828 def commiteditor(self): |
796 return cmdutil.getcommiteditor(edit=True, editform='histedit.mess') | 829 return cmdutil.getcommiteditor(edit=True, editform='histedit.mess') |
797 | 830 |
798 def findoutgoing(ui, repo, remote=None, force=False, opts=None): | 831 def findoutgoing(ui, repo, remote=None, force=False, opts=None): |
1474 ['histedit-state', False, True, _('histedit in progress'), | 1507 ['histedit-state', False, True, _('histedit in progress'), |
1475 _("use 'hg histedit --continue' or 'hg histedit --abort'")]) | 1508 _("use 'hg histedit --continue' or 'hg histedit --abort'")]) |
1476 cmdutil.afterresolvedstates.append( | 1509 cmdutil.afterresolvedstates.append( |
1477 ['histedit-state', _('hg histedit --continue')]) | 1510 ['histedit-state', _('hg histedit --continue')]) |
1478 if ui.configbool("experimental", "histeditng"): | 1511 if ui.configbool("experimental", "histeditng"): |
1479 globals()['base'] = addhisteditaction(['base', 'b'])(base) | 1512 globals()['base'] = action(['base', 'b'], |
1513 _('checkout changeset and apply further changesets from there') | |
1514 )(base) |