fix(app): added/deleted file status now correctly calculated

This commit is contained in:
Adam
2026-02-02 10:55:15 -06:00
parent 23631a9393
commit 3b93e8d95c
5 changed files with 115 additions and 4 deletions

View File

@@ -188,6 +188,7 @@ export namespace Snapshot {
after: z.string(),
additions: z.number(),
deletions: z.number(),
status: z.enum(["added", "deleted", "modified"]).optional(),
})
.meta({
ref: "FileDiff",
@@ -196,6 +197,23 @@ export namespace Snapshot {
export async function diffFull(from: string, to: string): Promise<FileDiff[]> {
const git = gitdir()
const result: FileDiff[] = []
const status = new Map<string, "added" | "deleted" | "modified">()
const statuses =
await $`git -c core.autocrlf=false -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --name-status --no-renames ${from} ${to} -- .`
.quiet()
.cwd(Instance.directory)
.nothrow()
.text()
for (const line of statuses.trim().split("\n")) {
if (!line) continue
const [code, file] = line.split("\t")
if (!code || !file) continue
const kind = code.startsWith("A") ? "added" : code.startsWith("D") ? "deleted" : "modified"
status.set(file, kind)
}
for await (const line of $`git -c core.autocrlf=false -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --no-renames --numstat ${from} ${to} -- .`
.quiet()
.cwd(Instance.directory)
@@ -224,6 +242,7 @@ export namespace Snapshot {
after,
additions: Number.isFinite(added) ? added : 0,
deletions: Number.isFinite(deleted) ? deleted : 0,
status: status.get(file) ?? "modified",
})
}
return result

View File

@@ -749,6 +749,52 @@ test("revert preserves file that existed in snapshot when deleted then recreated
})
})
test("diffFull sets status based on git change type", async () => {
await using tmp = await bootstrap()
await Instance.provide({
directory: tmp.path,
fn: async () => {
await Bun.write(`${tmp.path}/grow.txt`, "one\n")
await Bun.write(`${tmp.path}/trim.txt`, "line1\nline2\n")
await Bun.write(`${tmp.path}/delete.txt`, "gone")
const before = await Snapshot.track()
expect(before).toBeTruthy()
await Bun.write(`${tmp.path}/grow.txt`, "one\ntwo\n")
await Bun.write(`${tmp.path}/trim.txt`, "line1\n")
await $`rm ${tmp.path}/delete.txt`.quiet()
await Bun.write(`${tmp.path}/added.txt`, "new")
const after = await Snapshot.track()
expect(after).toBeTruthy()
const diffs = await Snapshot.diffFull(before!, after!)
expect(diffs.length).toBe(4)
const added = diffs.find((d) => d.file === "added.txt")
expect(added).toBeDefined()
expect(added!.status).toBe("added")
const deleted = diffs.find((d) => d.file === "delete.txt")
expect(deleted).toBeDefined()
expect(deleted!.status).toBe("deleted")
const grow = diffs.find((d) => d.file === "grow.txt")
expect(grow).toBeDefined()
expect(grow!.status).toBe("modified")
expect(grow!.additions).toBeGreaterThan(0)
expect(grow!.deletions).toBe(0)
const trim = diffs.find((d) => d.file === "trim.txt")
expect(trim).toBeDefined()
expect(trim!.status).toBe("modified")
expect(trim!.additions).toBe(0)
expect(trim!.deletions).toBeGreaterThan(0)
},
})
})
test("diffFull with new file additions", async () => {
await using tmp = await bootstrap()
await Instance.provide({