From 8add1b1ef5418c7d306b026f77e877cb25d0d2a6 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sun, 7 Feb 2021 15:36:31 -0800 Subject: [PATCH] reset: add a "Restore Worktree" action Add an action that restores the worktree to the state of a previous commit using "git read-tree". Closes #890 Signed-off-by: David Aguilar --- cola/cmds.py | 33 +++++++++++++++++++++++++++++++++ cola/guicmds.py | 8 ++++++++ cola/widgets/dag.py | 24 ++++++++++++++++++++---- cola/widgets/main.py | 10 ++++++++++ cola/widgets/toolbar.py | 1 + cola/widgets/toolbarcmds.py | 6 ++++++ 6 files changed, 78 insertions(+), 4 deletions(-) diff --git a/cola/cmds.py b/cola/cmds.py index d2355d6c..f1810d00 100644 --- a/cola/cmds.py +++ b/cola/cmds.py @@ -582,6 +582,39 @@ class ResetHard(ResetCommand): return self.git.reset(self.ref, '--', hard=True) +class RestoreWorktree(ConfirmAction): + """Reset the worktree using the "git read-tree" command""" + @staticmethod + def tooltip(ref): + tooltip = N_( + 'The worktree will be restored using "git read-tree --reset -u %s"' + ) + return tooltip % ref + + def __init__(self, context, ref): + super(RestoreWorktree, self).__init__(context) + self.ref = ref + + def action(self): + return self.git.read_tree(self.ref, reset=True, u=True) + + def command(self): + return 'git read-tree --reset -u %s' % self.ref + + def error_message(self): + return N_('Error') + + def success(self): + self.model.update_file_status() + + def confirm(self): + title = N_('Restore Worktree') + question = N_('Restore Worktree to %s?') % self.ref + info = self.tooltip(self.ref) + ok_text = N_('Restore Worktree') + return Interaction.confirm(title, question, info, ok_text) + + class UndoLastCommit(ResetCommand): """Undo the last commit""" # NOTE: this is the similar to ResetSoft() with an additional check for diff --git a/cola/guicmds.py b/cola/guicmds.py index 994e4394..cf9250a1 100644 --- a/cola/guicmds.py +++ b/cola/guicmds.py @@ -304,6 +304,14 @@ def reset_hard(context): cmds.do(cmds.ResetHard, context, ref) +def restore_worktree(context): + title = N_('Restore Worktree') + ok_text = N_('Restore Worktree') + ref = choose_ref(context, title, ok_text, default='HEAD^') + if ref: + cmds.do(cmds.RestoreWorktree, context, ref) + + def install(): """Install the GUI-model interaction hooks""" Interaction.choose_ref = staticmethod(choose_ref) diff --git a/cola/widgets/dag.py b/cola/widgets/dag.py index 84dbf9a7..452f365e 100644 --- a/cola/widgets/dag.py +++ b/cola/widgets/dag.py @@ -183,6 +183,10 @@ class ViewerMixin(object): context = self.context self.with_oid(lambda oid: cmds.do(cmds.ResetHard, context, ref=oid)) + def restore_worktree(self): + context = self.context + self.with_oid(lambda oid: cmds.do(cmds.RestoreWorktree, context, ref=oid)) + def checkout_detached(self): context = self.context self.with_oid(lambda oid: cmds.do(cmds.Checkout, context, [oid])) @@ -227,6 +231,7 @@ class ViewerMixin(object): self.menu_actions['reset_merge'].setEnabled(has_single_selection) self.menu_actions['reset_soft'].setEnabled(has_single_selection) self.menu_actions['reset_hard'].setEnabled(has_single_selection) + self.menu_actions['restore_worktree'].setEnabled(has_single_selection) self.menu_actions['revert'].setEnabled(has_single_selection) self.menu_actions['save_blob'].setEnabled(has_single_selection) @@ -249,6 +254,7 @@ class ViewerMixin(object): reset_menu = menu.addMenu(N_('Reset')) reset_menu.addAction(self.menu_actions['reset_soft']) reset_menu.addAction(self.menu_actions['reset_mixed']) + reset_menu.addAction(self.menu_actions['restore_worktree']) reset_menu.addSeparator() reset_menu.addAction(self.menu_actions['reset_keep']) reset_menu.addAction(self.menu_actions['reset_merge']) @@ -345,31 +351,41 @@ def viewer_actions(widget): 'reset_mixed': set_icon( icons.style_dialog_reset(), qtutils.add_action( - widget, N_('Reset Branch and Stage (Mixed)'), + widget, + N_('Reset Branch and Stage (Mixed)'), widget.proxy.reset_mixed ) ), 'reset_keep': set_icon( icons.style_dialog_reset(), qtutils.add_action( - widget, N_('Restore Worktree and Reset All (Keep Unstaged Edits)'), + widget, + N_('Restore Worktree and Reset All (Keep Unstaged Edits)'), widget.proxy.reset_keep ) ), 'reset_merge': set_icon( icons.style_dialog_reset(), qtutils.add_action( - widget, N_('Restore Worktree and Reset All (Merge)'), + widget, + N_('Restore Worktree and Reset All (Merge)'), widget.proxy.reset_merge ) ), 'reset_hard': set_icon( icons.style_dialog_reset(), qtutils.add_action( - widget, N_('Restore Worktree and Reset All (Hard)'), + widget, + N_('Restore Worktree and Reset All (Hard)'), widget.proxy.reset_hard ) ), + 'restore_worktree': set_icon( + icons.edit(), + qtutils.add_action( + widget, N_('Restore Worktree'), widget.proxy.restore_worktree + ) + ), 'save_blob': set_icon( icons.save(), qtutils.add_action( diff --git a/cola/widgets/main.py b/cola/widgets/main.py index 799cdf6f..79e6e072 100644 --- a/cola/widgets/main.py +++ b/cola/widgets/main.py @@ -401,6 +401,15 @@ class MainView(standard.MainWindow): self.reset_hard_action.setIcon(icons.style_dialog_reset()) self.reset_hard_action.setToolTip(cmds.ResetHard.tooltip('')) + self.restore_worktree_action = add_action( + self, N_('Restore Worktree'), + partial(guicmds.restore_worktree, context) + ) + self.restore_worktree_action.setIcon(icons.edit()) + self.restore_worktree_action.setToolTip( + cmds.RestoreWorktree.tooltip('') + ) + self.clone_repo_action = add_action( self, N_('Clone...'), partial(clone.clone, context) ) @@ -717,6 +726,7 @@ class MainView(standard.MainWindow): self.reset_menu.addSeparator() self.reset_menu.addAction(self.reset_soft_action) self.reset_menu.addAction(self.reset_mixed_action) + self.reset_menu.addAction(self.restore_worktree_action) self.reset_menu.addSeparator() self.reset_menu.addAction(self.reset_keep_action) self.reset_menu.addAction(self.reset_merge_action) diff --git a/cola/widgets/toolbar.py b/cola/widgets/toolbar.py index e1eb4005..02c11566 100644 --- a/cola/widgets/toolbar.py +++ b/cola/widgets/toolbar.py @@ -67,6 +67,7 @@ TREE_LAYOUT = { 'Commit::UnstageAll', 'Actions::ResetSoft', 'Actions::ResetMixed', + 'Actions::RestoreWorktree', 'Actions::ResetKeep', 'Actions::ResetHard', ], diff --git a/cola/widgets/toolbarcmds.py b/cola/widgets/toolbarcmds.py index fafa7c29..095e07c8 100644 --- a/cola/widgets/toolbarcmds.py +++ b/cola/widgets/toolbarcmds.py @@ -130,6 +130,12 @@ COMMANDS = { 'icon': 'style_dialog_reset', 'tooltip': cmds.ResetMixed.tooltip(''), }, + 'Actions::RestoreWorktree': { + 'title': 'Restore Worktree', + 'action': guicmds.restore_worktree, + 'icon': 'edit', + 'tooltip': cmds.RestoreWorktree.tooltip(''), + }, 'Actions::ResetKeep': { 'title': 'Restore Worktree and Reset All (Keep Unstaged Changes)', 'action': guicmds.reset_keep, -- 2.11.4.GIT