mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-06 08:24:46 +00:00
fix(diff): highlight symlinks from their stored target text
Working tree source context must match the symlink blob emitted by Git rather than the contents reached by following the link. Otherwise highlight runs do not cover the patch line and encoding fails the revision.
This commit is contained in:
@@ -519,3 +519,42 @@ test.skipIf(process.platform === "win32")(
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test.skipIf(process.platform === "win32")(
|
||||
"highlighted symlink replacements use stored link text instead of target contents",
|
||||
async () => {
|
||||
const { encodeDiffFrame, decodeDiffFrame } =
|
||||
await import("@getpaseo/protocol/binary-frames/index");
|
||||
const cwd = await mkdtemp(join(tmpdir(), "diff-highlighted-link-"));
|
||||
const git = (...args: string[]) => execFileSync("git", args, { cwd, encoding: "utf8" });
|
||||
const { symlink, unlink } = await import("node:fs/promises");
|
||||
try {
|
||||
git("init", "-b", "main");
|
||||
git("config", "user.name", "Test");
|
||||
git("config", "user.email", "test@example.com");
|
||||
await writeFile(join(cwd, "file.ts"), "export const old = 1;\n");
|
||||
await writeFile(join(cwd, "target.ts"), "export const entirelyDifferentLength = 2;\n");
|
||||
git("add", ".");
|
||||
git("-c", "commit.gpgsign=false", "commit", "-m", "base");
|
||||
await unlink(join(cwd, "file.ts"));
|
||||
await symlink("target.ts", join(cwd, "file.ts"));
|
||||
const comparison = await listComparison({
|
||||
cwd,
|
||||
base: { kind: "rev", rev: "HEAD" },
|
||||
head: { kind: "worktree" },
|
||||
});
|
||||
try {
|
||||
const record = await readBody(comparison);
|
||||
expect(record.body.hunks.flatMap((hunk) => hunk.lines)).toContainEqual(
|
||||
expect.objectContaining({ type: "add", content: "target.ts" }),
|
||||
);
|
||||
const frame = { opcode: 0x41 as const, slot: 0, revision: 1, files: [record.body] };
|
||||
expect(decodeDiffFrame(encodeDiffFrame(frame))).toEqual(frame);
|
||||
} finally {
|
||||
await comparison.close();
|
||||
}
|
||||
} finally {
|
||||
await rm(cwd, { recursive: true, force: true });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { lstat, readlink } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
import { readGitFileContents, readGitFileContentAtRef } from "../../utils/git-file-contents.js";
|
||||
import type { ListedFile } from "./git.js";
|
||||
|
||||
@@ -34,8 +36,12 @@ export class HighlightSources {
|
||||
? null
|
||||
: await this.content(contents, this.options.baseSha, file.entry.oldPath ?? file.entry.path);
|
||||
let newFileContent: string | null | undefined;
|
||||
if (this.options.headSha !== null)
|
||||
if (this.options.headSha !== null) {
|
||||
newFileContent = await this.content(contents, this.options.headSha, file.entry.path);
|
||||
} else if (file.entry.change !== "deleted") {
|
||||
const path = resolve(this.options.cwd, file.entry.path);
|
||||
if ((await lstat(path)).isSymbolicLink()) newFileContent = await readlink(path);
|
||||
}
|
||||
return { oldFileContent, newFileContent };
|
||||
}
|
||||
private async load(start: number): Promise<Map<string, string | null> | null> {
|
||||
|
||||
Reference in New Issue
Block a user