1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-04 23:37:41 +02:00
This commit is contained in:
Jesse Duffield 2021-03-31 22:39:55 +11:00
parent 332a3c4cbf
commit 54910fdb76
9 changed files with 76 additions and 35 deletions

View File

@ -4,11 +4,10 @@ import (
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
) )
// GetFilesInDiff get the specified commit files // GetFilesInDiff get the specified commit files
func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool, patchManager *patch.PatchManager) ([]*models.CommitFile, error) { func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool) ([]*models.CommitFile, error) {
reverseFlag := "" reverseFlag := ""
if reverse { if reverse {
reverseFlag = " -R " reverseFlag = " -R "
@ -19,11 +18,11 @@ func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool, patchM
return nil, err return nil, err
} }
return c.getCommitFilesFromFilenames(filenames, to, patchManager), nil return c.getCommitFilesFromFilenames(filenames), nil
} }
// filenames string is something like "file1\nfile2\nfile3" // filenames string is something like "file1\nfile2\nfile3"
func (c *GitCommand) getCommitFilesFromFilenames(filenames string, parent string, patchManager *patch.PatchManager) []*models.CommitFile { func (c *GitCommand) getCommitFilesFromFilenames(filenames string) []*models.CommitFile {
commitFiles := make([]*models.CommitFile, 0) commitFiles := make([]*models.CommitFile, 0)
lines := strings.Split(strings.TrimRight(filenames, "\x00"), "\x00") lines := strings.Split(strings.TrimRight(filenames, "\x00"), "\x00")
@ -32,15 +31,10 @@ func (c *GitCommand) getCommitFilesFromFilenames(filenames string, parent string
// typical result looks like 'A my_file' meaning my_file was added // typical result looks like 'A my_file' meaning my_file was added
changeStatus := lines[i] changeStatus := lines[i]
name := lines[i+1] name := lines[i+1]
status := patch.UNSELECTED
if patchManager != nil && patchManager.To == parent {
status = patchManager.GetFileStatus(name)
}
commitFiles = append(commitFiles, &models.CommitFile{ commitFiles = append(commitFiles, &models.CommitFile{
Name: name, Name: name,
ChangeStatus: changeStatus, ChangeStatus: changeStatus,
PatchStatus: status,
}) })
} }

View File

@ -4,9 +4,6 @@ package models
type CommitFile struct { type CommitFile struct {
Name string Name string
// PatchStatus tells us whether the file has been wholly or partially added to a patch. We might want to pull this logic up into the gui package and make it a map like we do with cherry picked commits
PatchStatus int // one of 'WHOLE' 'PART' 'NONE'
ChangeStatus string // e.g. 'A' for added or 'M' for modified. This is based on the result from git diff --name-status ChangeStatus string // e.g. 'A' for added or 'M' for modified. This is based on the result from git diff --name-status
} }

View File

@ -1,7 +1,6 @@
package patch package patch
import ( import (
"errors"
"sort" "sort"
"strings" "strings"
@ -9,9 +8,11 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
type PatchStatus int
const ( const (
// UNSELECTED is for when the commit file has not been added to the patch in any way // UNSELECTED is for when the commit file has not been added to the patch in any way
UNSELECTED = iota UNSELECTED PatchStatus = iota
// WHOLE is for when you want to add the whole diff of a file to the patch, // WHOLE is for when you want to add the whole diff of a file to the patch,
// including e.g. if it was deleted // including e.g. if it was deleted
WHOLE WHOLE
@ -20,7 +21,7 @@ const (
) )
type fileInfo struct { type fileInfo struct {
mode int // one of WHOLE/PART mode PatchStatus
includedLineIndices []int includedLineIndices []int
diff string diff string
} }
@ -81,20 +82,25 @@ func (p *PatchManager) removeFile(info *fileInfo) {
info.includedLineIndices = nil info.includedLineIndices = nil
} }
func (p *PatchManager) ToggleFileWhole(filename string) error { func (p *PatchManager) AddFileWhole(filename string) error {
info, err := p.getFileInfo(filename) info, err := p.getFileInfo(filename)
if err != nil { if err != nil {
return err return err
} }
switch info.mode {
case UNSELECTED, PART: p.addFileWhole(info)
p.addFileWhole(info)
case WHOLE: return nil
p.removeFile(info) }
default:
return errors.New("unknown file mode") func (p *PatchManager) RemoveFile(filename string) error {
info, err := p.getFileInfo(filename)
if err != nil {
return err
} }
p.removeFile(info)
return nil return nil
} }
@ -216,7 +222,7 @@ func (p *PatchManager) RenderAggregatedPatchColored(plain bool) string {
return result return result
} }
func (p *PatchManager) GetFileStatus(filename string) int { func (p *PatchManager) GetFileStatus(filename string) PatchStatus {
info, ok := p.fileInfoMap[filename] info, ok := p.fileInfoMap[filename]
if !ok { if !ok {
return UNSELECTED return UNSELECTED

View File

@ -3,6 +3,7 @@ package gui
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/filetree"
) )
@ -104,7 +105,7 @@ func (gui *Gui) refreshCommitFilesView() error {
to := gui.State.Panels.CommitFiles.refName to := gui.State.Panels.CommitFiles.refName
from, reverse := gui.getFromAndReverseArgsForDiff(to) from, reverse := gui.getFromAndReverseArgsForDiff(to)
files, err := gui.GitCommand.GetFilesInDiff(from, to, reverse, gui.GitCommand.PatchManager) files, err := gui.GitCommand.GetFilesInDiff(from, to, reverse)
if err != nil { if err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
@ -137,8 +138,6 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
// TODO: if file is nil, toggle all leaves underneath on/off
toggleTheFile := func() error { toggleTheFile := func() error {
if !gui.GitCommand.PatchManager.Active() { if !gui.GitCommand.PatchManager.Active() {
if err := gui.startPatchManager(); err != nil { if err := gui.startPatchManager(); err != nil {
@ -146,15 +145,29 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error {
} }
} }
if err := gui.GitCommand.PatchManager.ToggleFileWhole(node.GetPath()); err != nil { // if there is any file that hasn't been fully added we'll fully add everything,
return err // otherwise we'll remove everything
adding := node.AnyFile(func(file *models.CommitFile) bool {
return gui.GitCommand.PatchManager.GetFileStatus(file.Name) != patch.WHOLE
})
err := node.ForEachFile(func(file *models.CommitFile) error {
if adding {
return gui.GitCommand.PatchManager.AddFileWhole(file.Name)
} else {
return gui.GitCommand.PatchManager.RemoveFile(file.Name)
}
})
if err != nil {
return gui.surfaceError(err)
} }
if gui.GitCommand.PatchManager.IsEmpty() { if gui.GitCommand.PatchManager.IsEmpty() {
gui.GitCommand.PatchManager.Reset() gui.GitCommand.PatchManager.Reset()
} }
return gui.refreshCommitFilesView() return gui.postRefreshUpdate(gui.Contexts.CommitFiles.Context)
} }
if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != gui.State.CommitFileChangeManager.GetParent() { if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != gui.State.CommitFileChangeManager.GetParent() {

View File

@ -2,6 +2,7 @@ package filetree
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -87,9 +88,9 @@ func (m *CommitFileChangeManager) ToggleCollapsed(path string) {
m.collapsedPaths.ToggleCollapsed(path) m.collapsedPaths.ToggleCollapsed(path)
} }
func (m *CommitFileChangeManager) Render(diffName string) []string { func (m *CommitFileChangeManager) Render(diffName string, patchManager *patch.PatchManager) []string {
return renderAux(m.tree, m.collapsedPaths, "", -1, func(n INode, depth int) string { return renderAux(m.tree, m.collapsedPaths, "", -1, func(n INode, depth int) string {
castN := n.(*CommitFileChangeNode) castN := n.(*CommitFileChangeNode)
return presentation.GetCommitFileLine(castN.NameAtDepth(depth), diffName, castN.File) return presentation.GetCommitFileLine(castN.NameAtDepth(depth), diffName, castN.File, patchManager)
}) })
} }

View File

@ -81,6 +81,21 @@ func (s *CommitFileChangeNode) Any(test func(node *CommitFileChangeNode) bool) b
}) })
} }
func (s *CommitFileChangeNode) Every(test func(node *CommitFileChangeNode) bool) bool {
return every(s, func(n INode) bool {
castNode := n.(*CommitFileChangeNode)
return test(castNode)
})
}
func (s *CommitFileChangeNode) EveryFile(test func(file *models.CommitFile) bool) bool {
return every(s, func(n INode) bool {
castNode := n.(*CommitFileChangeNode)
return castNode.File == nil || test(castNode.File)
})
}
func (n *CommitFileChangeNode) Flatten(collapsedPaths map[string]bool) []*CommitFileChangeNode { func (n *CommitFileChangeNode) Flatten(collapsedPaths map[string]bool) []*CommitFileChangeNode {
results := flatten(n, collapsedPaths) results := flatten(n, collapsedPaths)
nodes := make([]*CommitFileChangeNode, len(results)) nodes := make([]*CommitFileChangeNode, len(results))

View File

@ -77,6 +77,20 @@ func any(node INode, test func(INode) bool) bool {
return false return false
} }
func every(node INode, test func(INode) bool) bool {
if !test(node) {
return false
}
for _, child := range node.GetChildren() {
if !every(child, test) {
return false
}
}
return true
}
func flatten(node INode, collapsedPaths map[string]bool) []INode { func flatten(node INode, collapsedPaths map[string]bool) []INode {
result := []INode{} result := []INode{}
result = append(result, node) result = append(result, node)

View File

@ -465,7 +465,7 @@ func (gui *Gui) commitFilesListContext() *ListContext {
return [][]string{{utils.ColoredString("(none)", color.FgRed)}} return [][]string{{utils.ColoredString("(none)", color.FgRed)}}
} }
lines := gui.State.CommitFileChangeManager.Render(gui.State.Modes.Diffing.Ref) lines := gui.State.CommitFileChangeManager.Render(gui.State.Modes.Diffing.Ref, gui.GitCommand.PatchManager)
mappedLines := make([][]string, len(lines)) mappedLines := make([][]string, len(lines))
for i, line := range lines { for i, line := range lines {
mappedLines[i] = []string{line} mappedLines[i] = []string{line}

View File

@ -8,7 +8,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFile) string { func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFile, patchManager *patch.PatchManager) string {
yellow := color.New(color.FgYellow) yellow := color.New(color.FgYellow)
green := color.New(color.FgGreen) green := color.New(color.FgGreen)
defaultColor := color.New(theme.DefaultTextColor) defaultColor := color.New(theme.DefaultTextColor)
@ -22,7 +22,8 @@ func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFi
if diffName == name { if diffName == name {
colour = diffTerminalColor colour = diffTerminalColor
} else if commitFile != nil { } else if commitFile != nil {
switch commitFile.PatchStatus { status := patchManager.GetFileStatus(commitFile.Name)
switch status {
case patch.UNSELECTED: case patch.UNSELECTED:
colour = defaultColor colour = defaultColor
case patch.WHOLE: case patch.WHOLE: