From a8c149bfd541b6263bd1f1bc7946981bf5a24cd5 Mon Sep 17 00:00:00 2001 From: p0ny Date: Wed, 18 Mar 2026 16:32:42 +0800 Subject: [PATCH 1/6] Fix diff parser git header prefixes --- src/common/utils/git/diffParser.test.ts | 21 +++++++++++++++++++++ src/common/utils/git/diffParser.ts | 16 +++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/common/utils/git/diffParser.test.ts b/src/common/utils/git/diffParser.test.ts index 7847e254e4..b43c6a305a 100644 --- a/src/common/utils/git/diffParser.test.ts +++ b/src/common/utils/git/diffParser.test.ts @@ -121,6 +121,27 @@ describe("git diff parser (real repository)", () => { expect(nonPhantomLines.every((l) => l.startsWith("+"))).toBe(true); }); + it("should parse diff headers with non-literal path prefixes", () => { + const diffOutput = [ + "diff --git c/foo.ts w/foo.ts", + "index 1111111..2222222 100644", + "--- c/foo.ts", + "+++ w/foo.ts", + "@@ -1 +1 @@", + "-old line", + "+new line", + ].join("\n"); + + const fileDiffs = parseDiff(diffOutput); + const allHunks = extractAllHunks(fileDiffs); + + expect(fileDiffs).toHaveLength(1); + expect(fileDiffs[0].filePath).toBe("foo.ts"); + expect(fileDiffs[0].oldPath).toBeUndefined(); + expect(allHunks).toHaveLength(1); + expect(allHunks[0].content).toContain("+new line"); + }); + it("should normalize CRLF diff output (no \\r in hunk content)", () => { const diffOutput = [ diff --git a/src/common/utils/git/diffParser.ts b/src/common/utils/git/diffParser.ts index 85e04621a8..bc70b91680 100644 --- a/src/common/utils/git/diffParser.ts +++ b/src/common/utils/git/diffParser.ts @@ -95,15 +95,17 @@ export function parseDiff(diffOutput: string): FileDiff[] { }; for (const line of lines) { - // File header: diff --git a/... b/... + // File header: git emits path labels here, but they are not guaranteed to be literal a/ and b/. if (line.startsWith("diff --git ")) { finishFile(); - // Extract file paths from "diff --git a/path b/path" - const regex = /^diff --git a\/(.+) b\/(.+)$/; - const match = regex.exec(line); - if (match) { - const oldPath = match[1]; - const newPath = match[2]; + // Extract the trailing paths from "diff --git