diff --git a/pkg/git/diff.go b/pkg/git/diff.go index 3fa0f5262..d0fb24749 100644 --- a/pkg/git/diff.go +++ b/pkg/git/diff.go @@ -28,6 +28,9 @@ type FilePatch struct { Chunks Chunks } +const SRC_PREFIX = "caf67b1d-c9b7-44ba-9b85-bd94727547af" +const DST_PREFIX = "7dcfe536-96a9-49c5-8b86-7caa3d9e5e9c" + func Diff(rootDir, baseRef string) ([]FilePatch, error) { var result []FilePatch @@ -40,7 +43,8 @@ func Diff(rootDir, baseRef string) ([]FilePatch, error) { "--first-parent", "--find-renames", "--break-rewrites", - "--no-prefix", + "--src-prefix=" + SRC_PREFIX, + "--dst-prefix=" + DST_PREFIX, "--no-color", baseRef, "--", @@ -113,13 +117,13 @@ func parseDiff(scanner *linescanner.Scanner) ([]FilePatch, error) { } func parseDiffHeader(value string) (string, string, error) { - parts := strings.Split(value, " ") - fromPath, err := unquoteFilename(parts[2]) + rawFromPath, rawToPath := splitPaths(value) + fromPath, err := unquoteFilename(rawFromPath) if err != nil { return "", "", fmt.Errorf("error parsing header 'from' path: %w", err) } - toPath, err := unquoteFilename(parts[3]) + toPath, err := unquoteFilename(rawToPath) if err != nil { return "", "", fmt.Errorf("error parsing header 'to' path: %w", err) } @@ -127,6 +131,26 @@ func parseDiffHeader(value string) (string, string, error) { return fromPath, toPath, nil } +func splitPaths(value string) (fromPath string, toPath string) { + split1 := strings.Split(value, SRC_PREFIX)[1] + split2 := strings.Split(split1, DST_PREFIX) + + fromPath = strings.TrimSpace(split2[0]) + toPath = strings.TrimSpace(split2[1]) + + // handle trailing whitespaces and missing quotation marks + // e.g. `foo\\t.txt \"` + if strings.Contains(fromPath, "\"") { + fromPath = "\"" + strings.TrimSpace(strings.ReplaceAll(fromPath, "\"", "")) + "\"" + } + + if strings.Contains(toPath, "\"") { + toPath = "\"" + strings.ReplaceAll(toPath, "\"", "") + "\"" + } + + return fromPath, toPath +} + func parseChunkHeader(value string) (Chunk, error) { parts := strings.Split(value, " ") diff --git a/pkg/git/diff_test.go b/pkg/git/diff_test.go index 563e73a9e..5de2ff1a1 100644 --- a/pkg/git/diff_test.go +++ b/pkg/git/diff_test.go @@ -86,7 +86,7 @@ var _ = Describe("Diff", func() { When("paths contain characters requiring quoting", func() { fromPath := "from\t.txt" - toPath := "to\t.txt" + toPath := "to text.txt" BeforeEach(func() { writeFile(tempDir, fromPath, "1\n2") @@ -105,6 +105,15 @@ var _ = Describe("Diff", func() { {FromPath: fromPath, ToPath: toPath}, })) }) + + fromPath = "from bar.txt" + toPath = "to.txt" + + It("decodes the paths correctly with whitespace in from path", func() { + Expect(git.Diff(tempDir, baseSHA)).To(ConsistOf([]git.FilePatch{ + {FromPath: fromPath, ToPath: toPath}, + })) + }) }) When("a file contains changes", func() {