Fix deleted diff syntax highlighting
This commit is contained in:
@@ -81,6 +81,49 @@ describe("checkout git utilities", () => {
|
||||
expect(message).toBe("update file");
|
||||
});
|
||||
|
||||
it("preserves removed-line syntax highlighting with structured diffs", async () => {
|
||||
const originalContent = `/*
|
||||
comment line 1
|
||||
comment line 2
|
||||
comment line 3
|
||||
comment line 4
|
||||
comment line 5
|
||||
comment line 6
|
||||
old comment line
|
||||
comment line 8
|
||||
*/
|
||||
const x = 1;
|
||||
`;
|
||||
const updatedContent = `/*
|
||||
comment line 1
|
||||
comment line 2
|
||||
comment line 3
|
||||
comment line 4
|
||||
comment line 5
|
||||
comment line 6
|
||||
new comment line
|
||||
comment line 8
|
||||
*/
|
||||
const x = 1;
|
||||
`;
|
||||
|
||||
writeFileSync(join(repoDir, "example.ts"), originalContent);
|
||||
execSync("git add example.ts", { cwd: repoDir });
|
||||
execSync("git -c commit.gpgsign=false commit -m 'add multiline comment fixture'", {
|
||||
cwd: repoDir,
|
||||
});
|
||||
|
||||
writeFileSync(join(repoDir, "example.ts"), updatedContent);
|
||||
|
||||
const diff = await getCheckoutDiff(repoDir, { mode: "uncommitted", includeStructured: true });
|
||||
const file = diff.structured?.find((entry) => entry.path === "example.ts");
|
||||
const removedLine = file?.hunks[0]?.lines.find((line) => line.type === "remove");
|
||||
const addedLine = file?.hunks[0]?.lines.find((line) => line.type === "add");
|
||||
|
||||
expect(addedLine?.tokens).toEqual([{ text: "new comment line", style: "comment" }]);
|
||||
expect(removedLine?.tokens).toEqual([{ text: "old comment line", style: "comment" }]);
|
||||
});
|
||||
|
||||
it("returns lightweight checkout status for normal repos", async () => {
|
||||
const status = await getCheckoutStatusLite(repoDir);
|
||||
expect(status.isGit).toBe(true);
|
||||
|
||||
@@ -304,6 +304,23 @@ async function listCheckoutFileChanges(cwd: string, ref: string): Promise<Checko
|
||||
return Array.from(byPath.values());
|
||||
}
|
||||
|
||||
async function readGitFileContentAtRef(
|
||||
cwd: string,
|
||||
ref: string,
|
||||
path: string,
|
||||
): Promise<string | null> {
|
||||
try {
|
||||
const { stdout } = await execFileAsync("git", ["show", `${ref}:${path}`], {
|
||||
cwd,
|
||||
env: READ_ONLY_GIT_ENV,
|
||||
maxBuffer: SMALL_OUTPUT_MAX_BUFFER,
|
||||
});
|
||||
return stdout;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function tryResolveMergeBase(cwd: string, baseRef: string): Promise<string | null> {
|
||||
try {
|
||||
const { stdout } = await execGit(`git merge-base ${baseRef} HEAD`, {
|
||||
@@ -1239,6 +1256,7 @@ export async function getCheckoutDiff(
|
||||
|
||||
const trackedChanges = changes.filter((change) => !change.isUntracked);
|
||||
const untrackedChanges = changes.filter((change) => change.isUntracked === true);
|
||||
const trackedChangeByPath = new Map(trackedChanges.map((change) => [change.path, change]));
|
||||
|
||||
const trackedNumstatByPath =
|
||||
trackedChanges.length > 0
|
||||
@@ -1294,7 +1312,18 @@ export async function getCheckoutDiff(
|
||||
|
||||
if (compare.includeStructured) {
|
||||
const parsedTrackedFiles =
|
||||
trackedDiffText.length > 0 ? await parseAndHighlightDiff(trackedDiffText, cwd) : [];
|
||||
trackedDiffText.length > 0
|
||||
? await parseAndHighlightDiff(trackedDiffText, cwd, {
|
||||
getOldFileContent: async (file) => {
|
||||
const change = trackedChangeByPath.get(file.path);
|
||||
if (!change || change.isNew) {
|
||||
return null;
|
||||
}
|
||||
const refPath = change.oldPath ?? change.path;
|
||||
return readGitFileContentAtRef(cwd, refForDiff, refPath);
|
||||
},
|
||||
})
|
||||
: [];
|
||||
const parsedTrackedByPath = new Map(parsedTrackedFiles.map((file) => [file.path, file]));
|
||||
|
||||
for (const change of trackedChanges) {
|
||||
|
||||
Reference in New Issue
Block a user