diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2019-03-18 20:44:33 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2019-03-23 13:26:17 +1100 |
commit | ff97ef7b94b5ccfda1d8b98b0a7e21a779309fcc (patch) | |
tree | 3eea28e8b5e635e8b23138ecd9a5cdc7fe0c4e8a /pkg | |
parent | a2c780b085b4b5fecf387d4f848d562494ab51cc (diff) |
support discarding unstaged changes
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/git.go | 15 | ||||
-rw-r--r-- | pkg/commands/git_test.go | 41 | ||||
-rw-r--r-- | pkg/commands/os.go | 6 | ||||
-rw-r--r-- | pkg/gui/files_panel.go | 91 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 4 | ||||
-rw-r--r-- | pkg/i18n/dutch.go | 15 | ||||
-rw-r--r-- | pkg/i18n/english.go | 15 | ||||
-rw-r--r-- | pkg/i18n/polish.go | 15 |
8 files changed, 151 insertions, 51 deletions
diff --git a/pkg/commands/git.go b/pkg/commands/git.go index af39ab2d2..e674dc720 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -438,8 +438,8 @@ func (c *GitCommand) RebaseMode() (string, error) { } } -// RemoveFile directly -func (c *GitCommand) RemoveFile(file *File) error { +// DiscardAllFileChanges directly +func (c *GitCommand) DiscardAllFileChanges(file *File) error { // if the file isn't tracked, we assume you want to delete it quotedFileName := c.OSCommand.Quote(file.Name) if file.HasStagedChanges { @@ -450,7 +450,12 @@ func (c *GitCommand) RemoveFile(file *File) error { if !file.Tracked { return c.removeFile(file.Name) } - // if the file is tracked, we assume you want to just check it out + return c.DiscardUnstagedFileChanges(file) +} + +// DiscardUnstagedFileChanges directly +func (c *GitCommand) DiscardUnstagedFileChanges(file *File) error { + quotedFileName := c.OSCommand.Quote(file.Name) return c.OSCommand.RunCommand(fmt.Sprintf("git checkout -- %s", quotedFileName)) } @@ -575,7 +580,7 @@ func (c *GitCommand) ApplyPatch(patch string) (string, error) { return "", err } - defer func() { _ = c.OSCommand.RemoveFile(filename) }() + defer func() { _ = c.OSCommand.Remove(filename) }() return c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git apply --cached %s", c.OSCommand.Quote(filename))) } @@ -861,7 +866,7 @@ func (c *GitCommand) DiscardOldFileChanges(commits []*Commit, commitIndex int, f // check if file exists in previous commit (this command returns an error if the file doesn't exist) if err := c.OSCommand.RunCommand(fmt.Sprintf("git cat-file -e HEAD^:%s", fileName)); err != nil { - if err := c.OSCommand.RemoveFile(fileName); err != nil { + if err := c.OSCommand.Remove(fileName); err != nil { return err } if err := c.StageFile(fileName); err != nil { diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index 8fbdc1642..614ad527b 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -1140,8 +1140,8 @@ func TestGitCommandIsInMergeState(t *testing.T) { } } -// TestGitCommandRemoveFile is a function. -func TestGitCommandRemoveFile(t *testing.T) { +// TestGitCommandDiscardAllFileChanges is a function. +func TestGitCommandDiscardAllFileChanges(t *testing.T) { type scenario struct { testName string command func() (func(string, ...string) *exec.Cmd, *[][]string) @@ -1337,7 +1337,7 @@ func TestGitCommandRemoveFile(t *testing.T) { gitCmd := NewDummyGitCommand() gitCmd.OSCommand.command, cmdsCalled = s.command() gitCmd.removeFile = s.removeFile - s.test(cmdsCalled, gitCmd.RemoveFile(s.file)) + s.test(cmdsCalled, gitCmd.DiscardAllFileChanges(s.file)) }) } } @@ -1932,3 +1932,38 @@ func TestGitCommandGetCommitFiles(t *testing.T) { }) } } + +// TestGitCommandDiscardUnstagedChanges is a function. +func TestGitCommandDiscardUnstagedChanges(t *testing.T) { + type scenario struct { + testName string + file *File + command func(string, ...string) *exec.Cmd + test func(error) + } + + scenarios := []scenario{ + { + "valid case", + &File{Name: "test.txt"}, + test.CreateMockCommand(t, []*test.CommandSwapper{ + { + Expect: `git checkout -- "test.txt"`, + Replace: "echo", + }, + }), + func(err error) { + assert.NoError(t, err) + }, + }, + } + + gitCmd := NewDummyGitCommand() + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd.OSCommand.command = s.command + s.test(gitCmd.DiscardUnstagedFileChanges(s.file)) + }) + } +} diff --git a/pkg/commands/os.go b/pkg/commands/os.go index 9e0967cba..1fb8e8da6 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/os.go @@ -255,9 +255,9 @@ func (c *OSCommand) CreateTempFile(filename, content string) (string, error) { return tmpfile.Name(), nil } -// RemoveFile removes a file at the specified path -func (c *OSCommand) RemoveFile(filename string) error { - err := os.Remove(filename) +// Remove removes a file or directory at the specified path +func (c *OSCommand) Remove(filename string) error { + err := os.RemoveAll(filename) return WrapError(err) } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 843286e9e..deaffb83b 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -259,35 +259,6 @@ func (gui *Gui) handleAddPatch(g *gocui.Gui, v *gocui.View) error { return gui.Errors.ErrSubProcess } -func (gui *Gui) handleFileRemove(g *gocui.Gui, v *gocui.View) error { - file, err := gui.getSelectedFile(g) - if err != nil { - if err == gui.Errors.ErrNoFiles { - return nil - } - return err - } - var deleteVerb string - if file.Tracked { - deleteVerb = gui.Tr.SLocalize("checkout") - } else { - deleteVerb = gui.Tr.SLocalize("delete") - } - message := gui.Tr.TemplateLocalize( - "SureTo", - Teml{ - "deleteVerb": deleteVerb, - "fileName": file.Name, - }, - ) - return gui.createConfirmationPanel(g, v, strings.Title(deleteVerb)+" file", message, func(g *gocui.Gui, v *gocui.View) error { - if err := gui.GitCommand.RemoveFile(file); err != nil { - return gui.createErrorPanel(gui.g, err.Error()) - } - return gui.refreshFiles() - }, nil) -} - func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error { file, err := gui.getSelectedFile(g) if err != nil { @@ -521,3 +492,65 @@ func (gui *Gui) handleSoftReset(g *gocui.Gui, v *gocui.View) error { return gui.refreshFiles() }, nil) } + +type discardOption struct { + handler func(fileName *commands.File) error + description string +} + +type discardOptionValue int + +// GetDisplayStrings is a function. +func (r *discardOption) GetDisplayStrings(isFocused bool) []string { + return []string{r.description} +} + +func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error { + file, err := gui.getSelectedFile(g) + if err != nil { + if err != gui.Errors.ErrNoFiles { + return err + } + return nil + } + + options := []*discardOption{ + { + description: gui.Tr.SLocalize("discardAllChanges"), + handler: func(file *commands.File) error { + if err := gui.GitCommand.DiscardAllFileChanges(file); err != nil { + return err + } + + return gui.refreshFiles() + }, + }, + { + description: gui.Tr.SLocalize("cancel"), + handler: func(file *commands.File) error { + return nil + }, + }, + } + + if file.HasStagedChanges && file.HasUnstagedChanges { + discardUnstagedChanges := &discardOption{ + description: gui.Tr.SLocalize("discardUnstagedChanges"), + handler: func(file *commands.File) error { + if err := gui.GitCommand.DiscardUnstagedFileChanges(file); err != nil { + return err + } + + return gui.refreshFiles() + }, + } + + options = append(options[:1], append([]*discardOption{discardUnstagedChanges}, options[1:]...)...) + } + + handleMenuPress := func(index int) error { + return options[index].handler(file) + } + + return gui.createMenu(file.Name, options, handleMenuPress) +} diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index ae8858124..172e76896 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -176,8 +176,8 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { ViewName: "files", Key: 'd', Modifier: gocui.ModNone, - Handler: gui.handleFileRemove, - Description: gui.Tr.SLocalize("removeFile"), + Handler: gui.handleCreateDiscardMenu, + Description: gui.Tr.SLocalize("viewDiscardOptions"), }, { ViewName: "files", Key: 'e', diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 77b3052d9..add38dd59 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -383,9 +383,6 @@ func addDutch(i18nObject *i18n.Bundle) error { ID: "GitconfigParseErr", Other: `Gogit kon je gitconfig bestand niet goed parsen door de aanwezigheid van losstaande '\' tekens. Het weghalen van deze tekens zou het probleem moeten oplossen. `, }, &i18n.Message{ - ID: "removeFile", - Other: `Verwijder als untracked / uitchecken wordt gevolgd (ga weg)`, - }, &i18n.Message{ ID: "editFile", Other: `verander bestand`, }, &i18n.Message{ @@ -685,6 +682,18 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "StashPrefix", Other: "Auto-stashing changes for ", + }, &i18n.Message{ + ID: "viewDiscardOptions", + Other: "view 'discard changes' options", + }, &i18n.Message{ + ID: "cancel", + Other: "cancel", + }, &i18n.Message{ + ID: "discardAllChanges", + Other: "discard all changes", + }, &i18n.Message{ + ID: "discardUnstagedChanges", + Other: "discard unstaged changes", }, ) } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 09805540a..7f22e82bd 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -448,9 +448,6 @@ func addEnglish(i18nObject *i18n.Bundle) error { ID: "GitconfigParseErr", Other: `Gogit failed to parse your gitconfig file due to the presence of unquoted '\' characters. Removing these should fix the issue.`, }, &i18n.Message{ - ID: "removeFile", - Other: `delete if untracked / checkout if tracked`, - }, &i18n.Message{ ID: "editFile", Other: `edit file`, }, &i18n.Message{ @@ -708,6 +705,18 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "StashPrefix", Other: "Auto-stashing changes for ", + }, &i18n.Message{ + ID: "viewDiscardOptions", + Other: "view 'discard changes' options", + }, &i18n.Message{ + ID: "cancel", + Other: "cancel", + }, &i18n.Message{ + ID: "discardAllChanges", + Other: "discard all changes", + }, &i18n.Message{ + ID: "discardUnstagedChanges", + Other: "discard unstaged changes", }, ) } diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go index 951bc3728..b8e43059f 100644 --- a/pkg/i18n/polish.go +++ b/pkg/i18n/polish.go @@ -372,9 +372,6 @@ func addPolish(i18nObject *i18n.Bundle) error { ID: "AnonymousReportingPrompt", Other: "Włączyć anonimowe raportowanie błędów w celu pomocy w usprawnianiu lazygita (enter/esc)?", }, &i18n.Message{ - ID: "removeFile", - Other: `usuń jeśli nie śledzony / przełącz jeśli śledzony`, - }, &i18n.Message{ ID: "editFile", Other: `edytuj plik`, }, &i18n.Message{ @@ -668,6 +665,18 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "StashPrefix", Other: "Auto-stashing changes for ", + }, &i18n.Message{ + ID: "viewDiscardOptions", + Other: "view 'discard changes' options", + }, &i18n.Message{ + ID: "cancel", + Other: "cancel", + }, &i18n.Message{ + ID: "discardAllChanges", + Other: "discard all changes", + }, &i18n.Message{ + ID: "discardUnstagedChanges", + Other: "discard unstaged changes", }, ) } |