authorgravatar for admin@snappeh.comTristan Knight <admin@snappeh.com> 2026-09-24 10:42:42+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-24 15:12:42+05:30
logb2b43bef73447c483ceae486890cb79f01c369cb
tree66b61e6c4c05a62b131034030597c1da7dd662ef
parente67abcf798f8c4d8458755e3b4dde02c2c1f628b
signature Signed by PGP key B5690EEEBB952194

fix(server): preserve racy edits in review diff previews (#12613)

Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>

2 files changed, 54 insertions(+), 1 deletions(-)

apps/server/src/vcs/GitVcsDriverCore.test.ts+45
......@@ -1449,6 +1449,51 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => {
14491449 }),
14501450 );
14511451
1452 for (const [timestamp, splitIndex] of [
1453 [1_700_000_000, false],
1454 [1_700_000_000.9999, false],
1455 [1_700_000_000, true],
1456 [1_700_000_000.9999, true],
1457 ] as const) {
1458 it.effect(
1459 `preserves same-size edits with a racy review index (${timestamp}, split: ${splitIndex})`,
1460 () =>
1461 Effect.gen(function* () {
1462 const cwd = yield* makeTmpDir();
1463 yield* initRepoWithCommit(cwd);
1464 const driver = yield* GitVcsDriver.GitVcsDriver;
1465 const fileSystem = yield* FileSystem.FileSystem;
1466 const path = yield* Path.Path;
1467 const filePath = path.join(cwd, "tracked.txt");
1468 const indexPath = path.join(cwd, ".git", "index");
1469 // Reproduce a same-timestamp edit without relying on filesystem clock resolution.
1470 yield* git(cwd, ["config", "core.trustctime", "false"]);
1471 yield* writeTextFile(cwd, "tracked.txt", "before\n");
1472 yield* fileSystem.utimes(filePath, timestamp, timestamp);
1473 yield* git(cwd, ["add", "tracked.txt"]);
1474 yield* git(cwd, ["commit", "-m", "record racy file"]);
1475 if (splitIndex) yield* git(cwd, ["update-index", "--split-index"]);
1476 yield* fileSystem.utimes(indexPath, timestamp, timestamp);
1477 const originalIndex = yield* fileSystem.readFile(indexPath);
1478 const originalIndexMtime = (yield* fileSystem.stat(indexPath)).mtime;
1479 yield* writeTextFile(cwd, "tracked.txt", "after!\n");
1480 yield* fileSystem.utimes(filePath, timestamp, timestamp);
1481 yield* writeTextFile(cwd, "untracked.txt", "new\n");
1482
1483 const preview = yield* driver.getReviewDiffPreview({ cwd });
1484 const dirty = preview.sources.find((source) => source.kind === "working-tree")!;
1485 assert.deepStrictEqual(dirty.files, [
1486 { path: "tracked.txt", previousPath: null, additions: 1, deletions: 1 },
1487 { path: "untracked.txt", previousPath: null, additions: 1, deletions: 0 },
1488 ]);
1489 assert.include(dirty.diff, "-before");
1490 assert.include(dirty.diff, "+after!");
1491 assert.deepStrictEqual(yield* fileSystem.readFile(indexPath), originalIndex);
1492 assert.deepStrictEqual((yield* fileSystem.stat(indexPath)).mtime, originalIndexMtime);
1493 }),
1494 );
1495 }
1496
14521497 it.effect("keeps complete stats for files beyond the combined patch limit", () =>
14531498 Effect.gen(function* () {
14541499 const cwd = yield* makeTmpDir();
apps/server/src/vcs/GitVcsDriverCore.ts+9-1
......@@ -2360,7 +2360,15 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function*
23602360 prefix: `t3code-review-index-${process.pid}-`,
23612361 });
23622362 const indexExists = yield* fileSystem.exists(indexPath);
2363 if (indexExists) yield* fileSystem.copyFile(indexPath, tempIndexPath);
2363 if (indexExists) {
2364 const { mtime } = yield* fileSystem.stat(indexPath);
2365 yield* fileSystem.copyFile(indexPath, tempIndexPath);
2366 // A newer copy timestamp hides racily clean edits. Round down before Git reads or rewrites it.
2367 const indexTime = Option.isSome(mtime)
2368 ? Math.max(0, Math.floor((mtime.value.getTime() - 1) / 1000))
2369 : 0;
2370 yield* fileSystem.utimes(tempIndexPath, indexTime, indexTime);
2371 }
23642372 const env = { GIT_INDEX_FILE: tempIndexPath } satisfies NodeJS.ProcessEnv;
23652373 const tempIndexConfig = [
23662374 "-c",