summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorMark Kopenga <mkopenga@gmail.com>2021-07-26 11:22:14 +0200
committerGitHub <noreply@github.com>2021-07-26 11:22:14 +0200
commiteec20b845da623310241ff98d44091bcfa15bd3e (patch)
tree00ca72098bea10917cee202b94114c2e8d9c8157 /pkg
parent9b57b73f41fb40acd88b941aaa6a256761be0a3a (diff)
parentfc76b44b4569247462462db0126a739d87781888 (diff)
Merge pull request #1392 from mjarkk/parcally-fix-1385
Change the way file statuses are loaded
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/loading_files.go27
-rw-r--r--pkg/commands/loading_files_test.go34
-rw-r--r--pkg/gui/filetree/file_node.go4
-rw-r--r--pkg/gui/presentation/commit_files.go1
-rw-r--r--pkg/gui/presentation/files.go2
-rw-r--r--pkg/utils/lines.go12
-rw-r--r--pkg/utils/slice_test.go32
7 files changed, 94 insertions, 18 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) {
@@ -109,6 +109,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)
+ },
+ },
}
for _, s := range scenarios {
diff --git a/pkg/gui/filetree/file_node.go b/pkg/gui/filetree/file_node.go
index 4df8bf5bf..cb545d391 100644
--- a/pkg/gui/filetree/file_node.go
+++ b/pkg/gui/filetree/file_node.go
@@ -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
diff --git a/pkg/gui/presentation/commit_files.go b/pkg/gui/presentation/commit_files.go
index 94116066a..7e9d4bdfa 100644
--- a/pkg/gui/presentation/commit_files.go
+++ b/pkg/gui/presentation/commit_files.go
@@ -28,6 +28,7 @@ func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFi
}
}
+ name = utils.EscapeSpecialChars(name)
if commitFile == nil {
return colour.Sprint(name)
}
diff --git a/pkg/gui/presentation/files.go b/pkg/gui/presentation/files.go
index 96fdbaa1f..8b3aacf56 100644
--- a/pkg/gui/presentation/files.go
+++ b/pkg/gui/presentation/files.go
@@ -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)
diff --git a/pkg/utils/lines.go b/pkg/utils/lines.go
index 4c654d888..9aea84bff 100644
--- a/pkg/utils/lines.go
+++ b/pkg/utils/lines.go
@@ -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)
+}
diff --git a/pkg/utils/slice_test.go b/pkg/utils/slice_test.go
index 858b1b904..491968cb4 100644
--- a/pkg/utils/slice_test.go
+++ b/pkg/utils/slice_test.go
@@ -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))
+ })
+ }
+}