mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-21 20:04:27 +00:00
fix(vcs): avoid unbounded diff memory usage (#25581)
This commit is contained in:
@@ -114,6 +114,53 @@ describe("Git", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("patch() returns capped native patch output", async () => {
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
await fs.writeFile(path.join(tmp.path, weird), "before\n", "utf-8")
|
||||
await fs.writeFile(path.join(tmp.path, "other.txt"), "old\n", "utf-8")
|
||||
await $`git add .`.cwd(tmp.path).quiet()
|
||||
await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet()
|
||||
await fs.writeFile(path.join(tmp.path, weird), "after\n", "utf-8")
|
||||
await fs.writeFile(path.join(tmp.path, "other.txt"), "new\n", "utf-8")
|
||||
|
||||
await withGit(async (rt) => {
|
||||
const [patch, all, capped] = await Promise.all([
|
||||
rt.runPromise(Git.Service.use((git) => git.patch(tmp.path, "HEAD", weird, { context: 2_147_483_647 }))),
|
||||
rt.runPromise(Git.Service.use((git) => git.patchAll(tmp.path, "HEAD", { context: 2_147_483_647 }))),
|
||||
rt.runPromise(Git.Service.use((git) => git.patch(tmp.path, "HEAD", weird, { maxOutputBytes: 1 }))),
|
||||
])
|
||||
|
||||
expect(patch.truncated).toBe(false)
|
||||
expect(patch.text).toContain("diff --git")
|
||||
expect(patch.text).toContain("-before")
|
||||
expect(patch.text).toContain("+after")
|
||||
expect(all.truncated).toBe(false)
|
||||
expect(all.text).toContain("diff --git")
|
||||
expect(all.text).toContain("other.txt")
|
||||
expect(all.text).toContain("+new")
|
||||
expect(capped.truncated).toBe(true)
|
||||
expect(capped.text).toBe("")
|
||||
})
|
||||
})
|
||||
|
||||
test("patchUntracked() and statUntracked() handle added files", async () => {
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
await fs.writeFile(path.join(tmp.path, weird), "one\ntwo\n", "utf-8")
|
||||
|
||||
await withGit(async (rt) => {
|
||||
const [patch, stat] = await Promise.all([
|
||||
rt.runPromise(Git.Service.use((git) => git.patchUntracked(tmp.path, weird, { context: 2_147_483_647 }))),
|
||||
rt.runPromise(Git.Service.use((git) => git.statUntracked(tmp.path, weird))),
|
||||
])
|
||||
|
||||
expect(patch.truncated).toBe(false)
|
||||
expect(patch.text).toContain("diff --git")
|
||||
expect(patch.text).toContain("+one")
|
||||
expect(patch.text).toContain("+two")
|
||||
expect(stat).toEqual(expect.objectContaining({ file: weird, additions: 2, deletions: 0 }))
|
||||
})
|
||||
})
|
||||
|
||||
test("show() returns empty text for binary blobs", async () => {
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
await fs.writeFile(path.join(tmp.path, "bin.dat"), new Uint8Array([0, 1, 2, 3]))
|
||||
|
||||
@@ -234,6 +234,7 @@ describe("Vcs diff", () => {
|
||||
}),
|
||||
]),
|
||||
)
|
||||
expect(diff.find((item) => item.file === "file.txt")?.patch).toContain("diff --git")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -259,6 +260,34 @@ describe("Vcs diff", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("diff('git') keeps batched patches aligned for type changes", async () => {
|
||||
if (process.platform === "win32") return
|
||||
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
await fs.writeFile(path.join(tmp.path, "a.txt"), "old\n", "utf-8")
|
||||
await fs.writeFile(path.join(tmp.path, "b.txt"), "old\n", "utf-8")
|
||||
await $`git add .`.cwd(tmp.path).quiet()
|
||||
await $`git commit --no-gpg-sign -m "add files"`.cwd(tmp.path).quiet()
|
||||
await fs.unlink(path.join(tmp.path, "a.txt"))
|
||||
await fs.symlink("target", path.join(tmp.path, "a.txt"))
|
||||
await fs.writeFile(path.join(tmp.path, "b.txt"), "new\n", "utf-8")
|
||||
|
||||
await withVcsOnly(tmp.path, async () => {
|
||||
const diff = await AppRuntime.runPromise(
|
||||
Effect.gen(function* () {
|
||||
const vcs = yield* Vcs.Service
|
||||
return yield* vcs.diff("git")
|
||||
}),
|
||||
)
|
||||
const a = diff.find((item) => item.file === "a.txt")
|
||||
const b = diff.find((item) => item.file === "b.txt")
|
||||
|
||||
expect(a?.patch).toContain("deleted file mode")
|
||||
expect(a?.patch).toContain("new file mode")
|
||||
expect(b?.patch).toContain("+new")
|
||||
})
|
||||
})
|
||||
|
||||
test("diff('branch') returns changes against default branch", async () => {
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
await $`git branch -M main`.cwd(tmp.path).quiet()
|
||||
|
||||
Reference in New Issue
Block a user