fix(opencode): batch snapshot revert without reordering (#20564)

This commit is contained in:
Kit Langton
2026-04-01 23:46:06 +00:00
committed by GitHub
parent 802d165572
commit 48db7cf07a
2 changed files with 173 additions and 11 deletions
@@ -1233,3 +1233,80 @@ test("revert with overlapping files across patches uses first patch hash", async
},
})
})
test("revert preserves patch order when the same hash appears again", async () => {
await using tmp = await bootstrap()
await Instance.provide({
directory: tmp.path,
fn: async () => {
await $`mkdir -p ${tmp.path}/foo`.quiet()
await Filesystem.write(`${tmp.path}/foo/bar`, "v1")
await Filesystem.write(`${tmp.path}/a.txt`, "v1")
const snap1 = await Snapshot.track()
expect(snap1).toBeTruthy()
await $`rm -rf ${tmp.path}/foo`.quiet()
await Filesystem.write(`${tmp.path}/foo`, "v2")
await Filesystem.write(`${tmp.path}/a.txt`, "v2")
const snap2 = await Snapshot.track()
expect(snap2).toBeTruthy()
await $`rm -rf ${tmp.path}/foo`.quiet()
await Filesystem.write(`${tmp.path}/a.txt`, "v3")
await Snapshot.revert([
{ hash: snap1!, files: [fwd(tmp.path, "a.txt")] },
{ hash: snap2!, files: [fwd(tmp.path, "foo")] },
{ hash: snap1!, files: [fwd(tmp.path, "foo", "bar")] },
])
expect(await fs.readFile(`${tmp.path}/a.txt`, "utf-8")).toBe("v1")
expect((await fs.stat(`${tmp.path}/foo`)).isDirectory()).toBe(true)
expect(await fs.readFile(`${tmp.path}/foo/bar`, "utf-8")).toBe("v1")
},
})
})
test("revert handles large mixed batches across chunk boundaries", async () => {
await using tmp = await bootstrap()
await Instance.provide({
directory: tmp.path,
fn: async () => {
const base = Array.from({ length: 140 }, (_, i) => fwd(tmp.path, "batch", `${i}.txt`))
const fresh = Array.from({ length: 140 }, (_, i) => fwd(tmp.path, "fresh", `${i}.txt`))
await $`mkdir -p ${tmp.path}/batch ${tmp.path}/fresh`.quiet()
await Promise.all(base.map((file, i) => Filesystem.write(file, `base-${i}`)))
const snap = await Snapshot.track()
expect(snap).toBeTruthy()
await Promise.all(base.map((file, i) => Filesystem.write(file, `next-${i}`)))
await Promise.all(fresh.map((file, i) => Filesystem.write(file, `fresh-${i}`)))
const patch = await Snapshot.patch(snap!)
expect(patch.files.length).toBe(base.length + fresh.length)
await Snapshot.revert([patch])
await Promise.all(
base.map(async (file, i) => {
expect(await fs.readFile(file, "utf-8")).toBe(`base-${i}`)
}),
)
await Promise.all(
fresh.map(async (file) => {
expect(
await fs
.access(file)
.then(() => true)
.catch(() => false),
).toBe(false)
}),
)
},
})
})