From 0c0231c3e835ef93a7fe06a95c28bd00f1da6631 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 28 Mar 2020 12:43:31 +1100 Subject: autostash changes when pulling file into index --- pkg/commands/patch_rebases.go | 26 +++++++++++++++++++++----- pkg/gui/confirmation_panel.go | 6 +++++- pkg/gui/discard_changes_menu_panel.go | 4 ++-- pkg/gui/files_panel.go | 2 +- pkg/gui/patch_options_panel.go | 20 +++++++++++++++----- pkg/gui/undoing.go | 11 ++--------- pkg/i18n/english.go | 6 ++++++ 7 files changed, 52 insertions(+), 23 deletions(-) diff --git a/pkg/commands/patch_rebases.go b/pkg/commands/patch_rebases.go index 19116e071..eeeb0876c 100644 --- a/pkg/commands/patch_rebases.go +++ b/pkg/commands/patch_rebases.go @@ -131,14 +131,22 @@ func (c *GitCommand) MovePatchToSelectedCommit(commits []*Commit, sourceCommitId return c.GenericMerge("rebase", "continue") } -func (c *GitCommand) PullPatchIntoIndex(commits []*Commit, commitIdx int, p *PatchManager) error { +func (c *GitCommand) PullPatchIntoIndex(commits []*Commit, commitIdx int, p *PatchManager, stash bool) error { + if stash { + if err := c.StashSave(c.Tr.SLocalize("StashPrefix") + commits[commitIdx].Sha); err != nil { + return err + } + } + if err := c.BeginInteractiveRebaseForCommit(commits, commitIdx); err != nil { return err } if err := p.ApplyPatches(true); err != nil { - if err := c.GenericMerge("rebase", "abort"); err != nil { - return err + if c.WorkingTreeState() == "rebasing" { + if err := c.GenericMerge("rebase", "abort"); err != nil { + return err + } } return err } @@ -155,12 +163,20 @@ func (c *GitCommand) PullPatchIntoIndex(commits []*Commit, commitIdx int, p *Pat c.onSuccessfulContinue = func() error { // add patches to index if err := p.ApplyPatches(false); err != nil { - if err := c.GenericMerge("rebase", "abort"); err != nil { - return err + if c.WorkingTreeState() == "rebasing" { + if err := c.GenericMerge("rebase", "abort"); err != nil { + return err + } } return err } + if stash { + if err := c.StashDo(0, "apply"); err != nil { + return err + } + } + c.PatchManager.Reset() return nil } diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index 0e0a3ac63..815d5a0f9 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -127,7 +127,11 @@ func (gui *Gui) createPopupPanel(g *gocui.Gui, currentView *gocui.View, title, p } gui.renderString(g, "confirmation", prompt) - return gui.setKeyBindings(g, handleConfirm, handleClose, returnFocusOnClose) + if err := gui.setKeyBindings(g, handleConfirm, handleClose, returnFocusOnClose); err != nil { + return err + } + + return gui.refreshSidePanels(refreshOptions{}) }) return nil } diff --git a/pkg/gui/discard_changes_menu_panel.go b/pkg/gui/discard_changes_menu_panel.go index 46722e1e5..0f01ad964 100644 --- a/pkg/gui/discard_changes_menu_panel.go +++ b/pkg/gui/discard_changes_menu_panel.go @@ -18,7 +18,7 @@ func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error { displayString: gui.Tr.SLocalize("discardAllChanges"), onPress: func() error { if err := gui.GitCommand.DiscardAllFileChanges(file); err != nil { - return err + return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) }, @@ -30,7 +30,7 @@ func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error { displayString: gui.Tr.SLocalize("discardUnstagedChanges"), onPress: func() error { if err := gui.GitCommand.DiscardUnstagedFileChanges(file); err != nil { - return err + return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index d3ecbdce4..7cb094837 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -130,7 +130,7 @@ func (gui *Gui) stagedFiles() []*commands.File { func (gui *Gui) trackedFiles() []*commands.File { files := gui.State.Files - result := make([]*commands.File, 0) + result := make([]*commands.File, 0, len(files)) for _, file := range files { if file.Tracked { result = append(result, file) diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index b8e88d903..e51860b43 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -113,11 +113,21 @@ func (gui *Gui) handlePullPatchIntoWorkingTree() error { return err } - return gui.WithWaitingStatus(gui.Tr.SLocalize("RebasingStatus"), func() error { - commitIndex := gui.getPatchCommitIndex() - err := gui.GitCommand.PullPatchIntoIndex(gui.State.Commits, commitIndex, gui.GitCommand.PatchManager) - return gui.handleGenericMergeCommandResult(err) - }) + pull := func(stash bool) error { + return gui.WithWaitingStatus(gui.Tr.SLocalize("RebasingStatus"), func() error { + commitIndex := gui.getPatchCommitIndex() + err := gui.GitCommand.PullPatchIntoIndex(gui.State.Commits, commitIndex, gui.GitCommand.PatchManager, stash) + return gui.handleGenericMergeCommandResult(err) + }) + } + + if len(gui.trackedFiles()) > 0 { + return gui.createConfirmationPanel(gui.g, gui.g.CurrentView(), true, gui.Tr.SLocalize("MustStashTitle"), gui.Tr.SLocalize("MustStashWarning"), func(*gocui.Gui, *gocui.View) error { + return pull(true) + }, nil) + } else { + return pull(false) + } } func (gui *Gui) handleApplyPatch() error { diff --git a/pkg/gui/undoing.go b/pkg/gui/undoing.go index 9ce7f7b0e..d34bfe91d 100644 --- a/pkg/gui/undoing.go +++ b/pkg/gui/undoing.go @@ -155,15 +155,6 @@ type handleHardResetWithAutoStashOptions struct { // only to be used in the undo flow for now func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHardResetWithAutoStashOptions) error { - // if we have any modified tracked files we need to ask the user if they want us to stash for them - dirtyWorkingTree := false - for _, file := range gui.State.Files { - if file.Tracked { - dirtyWorkingTree = true - break - } - } - reset := func() error { if err := gui.resetToRef(commitSha, "hard", commands.RunCommandOptions{EnvVars: options.EnvVars}); err != nil { return gui.surfaceError(err) @@ -171,6 +162,8 @@ func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHar return nil } + // if we have any modified tracked files we need to ask the user if they want us to stash for them + dirtyWorkingTree := len(gui.trackedFiles()) > 0 if dirtyWorkingTree { // offer to autostash changes return gui.createConfirmationPanel(gui.g, gui.getBranchesView(), true, gui.Tr.SLocalize("AutoStashTitle"), gui.Tr.SLocalize("AutoStashPrompt"), func(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 018c76f5c..3aa11224e 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -1062,6 +1062,12 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "cantRedoWhileRebasing", Other: "Can't redo while rebasing", + }, &i18n.Message{ + ID: "MustStashWarning", + Other: "Pulling a patch out into the index requires stashing and unstashing your changes. If something goes wrong, you'll be able to access your files from the stash. Continue?", + }, &i18n.Message{ + ID: "MustStashTitle", + Other: "Must stash", }, ) } -- cgit v1.2.3