From 9a087d04ebaed311e0bd3d9cbd32dd2973f0406c Mon Sep 17 00:00:00 2001 From: mjarkk Date: Thu, 22 Jul 2021 12:02:41 +0200 Subject: [PATCH] Change the way file statuses are loaded This makes it so file statuses recived from git no longer get joined before spliting them again. --- pkg/commands/loading_files.go | 27 +++++++++++++----------- pkg/commands/loading_files_test.go | 34 ++++++++++++++++++++++++++++-- pkg/gui/presentation/files.go | 10 +++++++++ 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/pkg/commands/loading_files.go b/pkg/commands/loading_files.go index f85329f2f..2b9bfc2be 100644 --- a/pkg/commands/loading_files.go +++ b/pkg/commands/loading_files.go @@ -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 } diff --git a/pkg/commands/loading_files_test.go b/pkg/commands/loading_files_test.go index bb0a5971a..eefb8f924 100644 --- a/pkg/commands/loading_files_test.go +++ b/pkg/commands/loading_files_test.go @@ -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) }, }, diff --git a/pkg/gui/presentation/files.go b/pkg/gui/presentation/files.go index 96fdbaa1f..f45ef04d3 100644 --- a/pkg/gui/presentation/files.go +++ b/pkg/gui/presentation/files.go @@ -1,6 +1,8 @@ package presentation import ( + "strings" + "github.com/fatih/color" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/theme" @@ -48,6 +50,14 @@ func GetFileLine(hasUnstagedChanges bool, hasStagedChanges bool, name string, di output += restColor.Sprint(" ") } + name = strings.NewReplacer( + "\n", "\\n", + "\r", "\\r", + "\t", "\\t", + "\b", "\\b", + "\f", "\\f", + "\v", "\\v", + ).Replace(name) output += restColor.Sprint(name) if file != nil && file.IsSubmodule(submoduleConfigs) {