1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-22 05:29:44 +02:00

support discarding changes in dir

This commit is contained in:
Jesse Duffield 2021-03-15 22:29:34 +11:00
parent f871724ae6
commit 418621a9ff
4 changed files with 106 additions and 26 deletions

View File

@ -2,6 +2,7 @@ package commands
import ( import (
"fmt" "fmt"
"os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
@ -140,6 +141,47 @@ func (c *GitCommand) DiscardAllFileChanges(file *models.File) error {
return c.DiscardUnstagedFileChanges(file) return c.DiscardUnstagedFileChanges(file)
} }
func (c *GitCommand) DiscardAllDirChanges(node *models.StatusLineNode) error {
if err := c.RemoveUntrackedDirFiles(node); err != nil {
return err
}
quotedPath := c.OSCommand.Quote(node.GetPath())
if err := c.OSCommand.RunCommand("git checkout HEAD -- %s", quotedPath); err != nil {
return err
}
return nil
}
func (c *GitCommand) DiscardUnstagedDirChanges(node *models.StatusLineNode) error {
if err := c.RemoveUntrackedDirFiles(node); err != nil {
return err
}
quotedPath := c.OSCommand.Quote(node.GetPath())
if err := c.OSCommand.RunCommand("git checkout -- %s", quotedPath); err != nil {
return err
}
return nil
}
func (c *GitCommand) RemoveUntrackedDirFiles(node *models.StatusLineNode) error {
untrackedFilePaths := node.GetPathsMatching(
func(n *models.StatusLineNode) bool { return n.File != nil && !n.File.GetIsTracked() },
)
for _, path := range untrackedFilePaths {
err := os.Remove(path)
if err != nil {
return err
}
}
return nil
}
// DiscardUnstagedFileChanges directly // DiscardUnstagedFileChanges directly
func (c *GitCommand) DiscardUnstagedFileChanges(file *models.File) error { func (c *GitCommand) DiscardUnstagedFileChanges(file *models.File) error {
quotedFileName := c.OSCommand.Quote(file.Name) quotedFileName := c.OSCommand.Quote(file.Name)

View File

@ -188,3 +188,18 @@ func (s *StatusLineNode) compressAux() *StatusLineNode {
func (s *StatusLineNode) HasExactlyOneChild() bool { func (s *StatusLineNode) HasExactlyOneChild() bool {
return len(s.Children) == 1 return len(s.Children) == 1
} }
// This ignores the root
func (s *StatusLineNode) GetPathsMatching(test func(*StatusLineNode) bool) []string {
paths := []string{}
if test(s) {
paths = append(paths, s.GetPath())
}
for _, child := range s.Children {
paths = append(paths, child.GetPathsMatching(test)...)
}
return paths
}

View File

@ -1,35 +1,18 @@
package gui package gui
import ( func (gui *Gui) handleCreateDiscardMenu() error {
"github.com/jesseduffield/gocui" node := gui.getSelectedStatusNode()
) if node == nil {
func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
file := gui.getSelectedFile()
if file == nil {
return nil return nil
} }
var menuItems []*menuItem var menuItems []*menuItem
if node.File == nil {
submodules := gui.State.Submodules
if file.IsSubmodule(submodules) {
submodule := file.SubmoduleConfig(submodules)
menuItems = []*menuItem{
{
displayString: gui.Tr.LcSubmoduleStashAndReset,
onPress: func() error {
return gui.handleResetSubmodule(submodule)
},
},
}
} else {
menuItems = []*menuItem{ menuItems = []*menuItem{
{ {
displayString: gui.Tr.LcDiscardAllChanges, displayString: gui.Tr.LcDiscardAllChanges,
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.DiscardAllFileChanges(file); err != nil { if err := gui.GitCommand.DiscardAllDirChanges(node); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
@ -37,11 +20,11 @@ func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
}, },
} }
if file.HasStagedChanges && file.HasUnstagedChanges { if node.GetHasStagedChanges() && node.GetHasUnstagedChanges() {
menuItems = append(menuItems, &menuItem{ menuItems = append(menuItems, &menuItem{
displayString: gui.Tr.LcDiscardUnstagedChanges, displayString: gui.Tr.LcDiscardUnstagedChanges,
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.DiscardUnstagedFileChanges(file); err != nil { if err := gui.GitCommand.DiscardUnstagedDirChanges(node); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
@ -49,8 +32,48 @@ func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
}, },
}) })
} }
} else {
file := node.File
submodules := gui.State.Submodules
if file.IsSubmodule(submodules) {
submodule := file.SubmoduleConfig(submodules)
menuItems = []*menuItem{
{
displayString: gui.Tr.LcSubmoduleStashAndReset,
onPress: func() error {
return gui.handleResetSubmodule(submodule)
},
},
}
} else {
menuItems = []*menuItem{
{
displayString: gui.Tr.LcDiscardAllChanges,
onPress: func() error {
if err := gui.GitCommand.DiscardAllFileChanges(file); err != nil {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
},
},
}
if file.HasStagedChanges && file.HasUnstagedChanges {
menuItems = append(menuItems, &menuItem{
displayString: gui.Tr.LcDiscardUnstagedChanges,
onPress: func() error {
if err := gui.GitCommand.DiscardUnstagedFileChanges(file); err != nil {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
},
})
}
}
} }
return gui.createMenu(file.Name, menuItems, createMenuOptions{showCancel: true}) return gui.createMenu(node.GetPath(), menuItems, createMenuOptions{showCancel: true})
} }

View File

@ -408,7 +408,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
ViewName: "files", ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY}, Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey(config.Universal.Remove), Key: gui.getKey(config.Universal.Remove),
Handler: gui.handleCreateDiscardMenu, Handler: gui.wrappedHandler(gui.handleCreateDiscardMenu),
Description: gui.Tr.LcViewDiscardOptions, Description: gui.Tr.LcViewDiscardOptions,
OpensMenu: true, OpensMenu: true,
}, },