diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 265d6553e..159c88cca 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -27,8 +27,11 @@ func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir f for { f, err := stat(".git") - if err == nil && f.IsDir() { - return nil + if err == nil { + if f.IsDir() { + return nil + } + return errors.New("expected .git to be a directory") } if !os.IsNotExist(err) { @@ -274,8 +277,8 @@ func (c *GitCommand) Fetch(unamePassQuestion func(string) string, canAskForCrede } // ResetToCommit reset to commit -func (c *GitCommand) ResetToCommit(sha string) error { - return c.OSCommand.RunCommand(fmt.Sprintf("git reset %s", sha)) +func (c *GitCommand) ResetToCommit(sha string, strength string) error { + return c.OSCommand.RunCommand(fmt.Sprintf("git reset --%s %s", strength, sha)) } // NewBranch create new branch diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index 3358be054..0d59c30b7 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -616,12 +616,12 @@ func TestGitCommandResetToCommit(t *testing.T) { gitCmd := NewDummyGitCommand() gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { assert.EqualValues(t, "git", cmd) - assert.EqualValues(t, []string{"reset", "78976bc"}, args) + assert.EqualValues(t, []string{"reset", "--hard", "78976bc"}, args) return exec.Command("echo") } - assert.NoError(t, gitCmd.ResetToCommit("78976bc")) + assert.NoError(t, gitCmd.ResetToCommit("78976bc", "hard")) } // TestGitCommandNewBranch is a function. diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 98817bf59..c35b4adee 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -4,6 +4,7 @@ import ( "fmt" "strconv" + "github.com/fatih/color" "github.com/go-errors/errors" "github.com/jesseduffield/gocui" @@ -124,7 +125,8 @@ func (gui *Gui) handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error if commit == nil { panic(errors.New(gui.Tr.SLocalize("NoCommitsThisBranch"))) } - if err := gui.GitCommand.ResetToCommit(commit.Sha); err != nil { + + if err := gui.GitCommand.ResetToCommit(commit.Sha, "mixed"); err != nil { return gui.createErrorPanel(g, err.Error()) } if err := gui.refreshCommits(g); err != nil { @@ -554,3 +556,50 @@ func (gui *Gui) handleSquashAllAboveFixupCommits(g *gocui.Gui, v *gocui.View) er }) }, nil) } + +type resetOption struct { + description string + command string +} + +// GetDisplayStrings is a function. +func (r *resetOption) GetDisplayStrings(isFocused bool) []string { + return []string{r.description, color.New(color.FgRed).Sprint(r.command)} +} + +func (gui *Gui) handleCreateCommitResetMenu(g *gocui.Gui, v *gocui.View) error { + commit := gui.getSelectedCommit(g) + if commit == nil { + return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NoCommitsThisBranch")) + } + + strengths := []string{"soft", "mixed", "hard"} + options := make([]*resetOption, len(strengths)) + for i, strength := range strengths { + options[i] = &resetOption{ + description: fmt.Sprintf("%s reset", strength), + command: fmt.Sprintf("reset --%s %s", strength, commit.Sha), + } + } + + handleMenuPress := func(index int) error { + if err := gui.GitCommand.ResetToCommit(commit.Sha, strengths[index]); err != nil { + return err + } + + if err := gui.refreshCommits(g); err != nil { + return err + } + if err := gui.refreshFiles(); err != nil { + return err + } + if err := gui.resetOrigin(gui.getCommitsView()); err != nil { + return err + } + + gui.State.Panels.Commits.SelectedLine = 0 + return gui.handleCommitSelect(g, gui.getCommitsView()) + } + + return gui.createMenu(fmt.Sprintf("%s %s", gui.Tr.SLocalize("resetTo"), commit.Sha), options, len(options), handleMenuPress) +} diff --git a/pkg/gui/context.go b/pkg/gui/context.go index b741132ea..2cdc5c8c6 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -21,7 +21,11 @@ func (gui *Gui) contextTitleMap() map[string]map[string]string { } func (gui *Gui) setMainTitle() error { - currentViewName := gui.g.CurrentView().Name() + currentView := gui.g.CurrentView() + if currentView == nil { + return nil + } + currentViewName := currentView.Name() var newTitle string if context, ok := gui.State.Contexts[currentViewName]; ok { newTitle = gui.contextTitleMap()[currentViewName][context] diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index caab1bede..3d2001ac1 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -86,6 +86,10 @@ func (gui *Gui) refreshFiles() error { selectedFile, _ := gui.getSelectedFile(gui.g) filesView := gui.getFilesView() + if filesView == nil { + // if the filesView hasn't been instantiated yet we just return + return nil + } if err := gui.refreshStateFiles(); err != nil { return err } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 6bb32ea59..fd4ed7625 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -327,7 +327,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { ViewName: "commits", Key: 'g', Modifier: gocui.ModNone, - Handler: gui.handleResetToCommit, + Handler: gui.handleCreateCommitResetMenu, Description: gui.Tr.SLocalize("resetToThisCommit"), }, { ViewName: "commits", diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 489a5d955..97b49e76d 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -733,6 +733,9 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "SkipHookPrefixNotConfigured", Other: "Je hebt nog niet een commit bericht voorvoegsel ingesteld voor het overslaan van hooks. Set `git.skipHookPrefix = 'WIP'` in je config", + }, &i18n.Message{ + ID: "resetTo", + Other: `reset to`, }, ) } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index b6c8215d8..291f114e8 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -756,6 +756,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "SkipHookPrefixNotConfigured", Other: "You have not configured a commit message prefix for skipping hooks. Set `git.skipHookPrefix = 'WIP'` in your config", + }, &i18n.Message{ + ID: "resetTo", + Other: `reset to`, }, ) } diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go index 09ad7624f..8229dc5df 100644 --- a/pkg/i18n/polish.go +++ b/pkg/i18n/polish.go @@ -716,6 +716,9 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "SkipHookPrefixNotConfigured", Other: "You have not configured a commit message prefix for skipping hooks. Set `git.skipHookPrefix = 'WIP'` in your config", + }, &i18n.Message{ + ID: "resetTo", + Other: `reset to`, }, ) }