1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-20 05:19:24 +02:00

Merge pull request #1392 from mjarkk/parcally-fix-1385

Change the way file statuses are loaded
This commit is contained in:
Mark Kopenga 2021-07-26 11:22:14 +02:00 committed by GitHub
commit eec20b845d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 94 additions and 18 deletions

View File

@ -24,11 +24,10 @@ func (c *GitCommand) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
}
untrackedFilesArg := fmt.Sprintf("--untracked-files=%s", untrackedFilesSetting)
statusOutput, err := c.GitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
statusStrings, err := c.GitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
if err != nil {
c.Log.Error(err)
}
statusStrings := utils.SplitLines(statusOutput)
files := []*models.File{}
for _, statusString := range statusStrings {
@ -77,7 +76,7 @@ type GitStatusOptions struct {
UntrackedFilesArg string
}
func (c *GitCommand) GitStatus(opts GitStatusOptions) (string, error) {
func (c *GitCommand) GitStatus(opts GitStatusOptions) ([]string, error) {
noRenamesFlag := ""
if opts.NoRenames {
noRenamesFlag = "--no-renames"
@ -85,20 +84,24 @@ func (c *GitCommand) GitStatus(opts GitStatusOptions) (string, error) {
statusLines, err := c.RunCommandWithOutput("git status %s --porcelain -z %s", opts.UntrackedFilesArg, noRenamesFlag)
if err != nil {
return "", err
return []string{}, err
}
splitLines := strings.Split(statusLines, "\x00")
// if a line starts with 'R' then the next line is the original file.
for i := 0; i < len(splitLines)-1; i++ {
response := []string{}
for i := 0; i < len(splitLines); i++ {
original := splitLines[i]
if strings.HasPrefix(original, "R ") {
next := splitLines[i+1]
updated := "R " + next + RENAME_SEPARATOR + strings.TrimPrefix(original, "R ")
splitLines[i] = updated
splitLines = append(splitLines[0:i+1], splitLines[i+2:]...)
if len(original) < 2 {
continue
} else if strings.HasPrefix(original, "R ") {
// if a line starts with 'R' then the next line is the original file.
next := strings.TrimSpace(splitLines[i+1])
original = "R " + next + RENAME_SEPARATOR + strings.TrimPrefix(original, "R ")
i++
}
response = append(response, original)
}
return strings.Join(splitLines, "\n"), nil
return response, nil
}

View File

@ -31,8 +31,8 @@ func TestGitCommandGetStatusFiles(t *testing.T) {
"Several files found",
func(cmd string, args ...string) *exec.Cmd {
return secureexec.Command(
"echo",
"MM file1.txt\nA file3.txt\nAM file2.txt\n?? file4.txt\nUU file5.txt",
"printf",
`MM file1.txt\0A file3.txt\0AM file2.txt\0?? file4.txt\0UU file5.txt`,
)
},
func(files []*models.File) {
@ -106,6 +106,36 @@ func TestGitCommandGetStatusFiles(t *testing.T) {
},
}
assert.EqualValues(t, expected, files)
},
},
{
"File with new line char",
func(cmd string, args ...string) *exec.Cmd {
return secureexec.Command(
"printf",
`MM a\nb.txt`,
)
},
func(files []*models.File) {
assert.Len(t, files, 1)
expected := []*models.File{
{
Name: "a\nb.txt",
HasStagedChanges: true,
HasUnstagedChanges: true,
Tracked: true,
Added: false,
Deleted: false,
HasMergeConflicts: false,
HasInlineMergeConflicts: false,
DisplayString: "MM a\nb.txt",
Type: "other",
ShortStatus: "MM",
},
}
assert.EqualValues(t, expected, files)
},
},

View File

@ -1,8 +1,6 @@
package filetree
import (
"fmt"
"github.com/jesseduffield/lazygit/pkg/commands/models"
)
@ -182,7 +180,7 @@ func (s *FileNode) NameAtDepth(depth int) string {
prevName = join(splitPrevName[depth:])
}
return fmt.Sprintf("%s%s%s", prevName, " → ", name)
return prevName + " → " + name
}
return name

View File

@ -28,6 +28,7 @@ func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFi
}
}
name = utils.EscapeSpecialChars(name)
if commitFile == nil {
return colour.Sprint(name)
}

View File

@ -48,7 +48,7 @@ func GetFileLine(hasUnstagedChanges bool, hasStagedChanges bool, name string, di
output += restColor.Sprint(" ")
}
output += restColor.Sprint(name)
output += restColor.Sprint(utils.EscapeSpecialChars(name))
if file != nil && file.IsSubmodule(submoduleConfigs) {
output += utils.ColoredString(" (submodule)", theme.DefaultTextColor)

View File

@ -32,3 +32,15 @@ func NormalizeLinefeeds(str string) string {
str = strings.Replace(str, "\r", "", -1)
return str
}
// EscapeSpecialChars - Replaces all special chars like \n with \\n
func EscapeSpecialChars(str string) string {
return strings.NewReplacer(
"\n", "\\n",
"\r", "\\r",
"\t", "\\t",
"\b", "\\b",
"\f", "\\f",
"\v", "\\v",
).Replace(str)
}

View File

@ -133,3 +133,35 @@ func TestPrevIndex(t *testing.T) {
})
}
}
func TestEscapeSpecialChars(t *testing.T) {
type scenario struct {
testName string
input string
expected string
}
scenarios := []scenario{
{
"normal string",
"ab",
"ab",
},
{
"string with a special char",
"a\nb",
"a\\nb",
},
{
"multiple special chars",
"\n\r\t\b\f\v",
"\\n\\r\\t\\b\\f\\v",
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
assert.EqualValues(t, s.expected, EscapeSpecialChars(s.input))
})
}
}