fix(opencode): batch snapshot revert without reordering (#20564)
This commit is contained in:
@@ -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)
|
||||
}),
|
||||
)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user