fix(snapshot): remove orphaned tmp_pack files during cleanup#606
fix(snapshot): remove orphaned tmp_pack files during cleanup#606Olusammytee wants to merge 1 commit intoKilo-Org:devfrom
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (1 files)
|
There was a problem hiding this comment.
Pull request overview
Removes orphaned tmp_pack_* files from the snapshot git storage to prevent disk-space leaks, and adds logging/cleanup on failure paths to aid diagnosis (Fixes #471).
Changes:
- Run
cleanupTmpPacks()during scheduled snapshot cleanup and include removal counts in logs. - Add explicit exit-code handling for
git addandgit write-treeinSnapshot.track(), invoking tmp-pack cleanup on failure. - Introduce internal helper
cleanupTmpPacks()to deleteobjects/pack/tmp_pack_*files.
Comments suppressed due to low confidence (2)
packages/opencode/src/snapshot/index.ts:286
cleanupTmpPacks()returnstmpPacks.lengtheven though individualunlinkcalls can fail (errors are swallowed). This makestmpPackRemovedmisleading in logs and can hide partial cleanup failures. Consider either (a) counting only successful deletions (e.g., viaPromise.allSettled) or (b) renaming the metric totmpPackFound/tmpPackCandidatesand separately tracking failures.
const files = await fs.readdir(pack).catch(() => [])
const tmpPacks = files.filter((file) => file.startsWith("tmp_pack_"))
await Promise.all(tmpPacks.map((file) => fs.unlink(path.join(pack, file)).catch(() => undefined)))
return tmpPacks.length
packages/opencode/src/snapshot/index.ts:286
- This PR adds new cleanup behavior (
cleanupTmpPacks) and new early-return paths fortrack()whengit add/write-treefail, but there are no tests covering tmp-pack deletion or the new failure handling. Sincepackages/opencode/test/snapshot/snapshot.test.tsalready has extensive coverage for snapshots, consider adding a test that creates aobjects/pack/tmp_pack_*file under the snapshot gitdir and assertsSnapshot.cleanup()(and/or the failure path) removes it.
async function cleanupTmpPacks(git: string) {
const pack = path.join(git, "objects", "pack")
const files = await fs.readdir(pack).catch(() => [])
const tmpPacks = files.filter((file) => file.startsWith("tmp_pack_"))
await Promise.all(tmpPacks.map((file) => fs.unlink(path.join(pack, file)).catch(() => undefined)))
return tmpPacks.length
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const add = await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`.quiet().cwd(Instance.directory).nothrow() | ||
| if (add.exitCode !== 0) { | ||
| const tmpPackRemoved = await cleanupTmpPacks(git) | ||
| log.warn("snapshot add failed", { | ||
| exitCode: add.exitCode, | ||
| stderr: add.stderr.toString(), | ||
| stdout: add.stdout.toString(), | ||
| tmpPackRemoved, | ||
| }) | ||
| return |
There was a problem hiding this comment.
cleanupTmpPacks(git) is triggered on git add / write-tree failures. If those failures are caused by a concurrent Snapshot.cleanup() running git gc (or another git maintenance operation) in the same repo, this could delete tmp_pack_* files while repack is still in progress and potentially corrupt the snapshot repository. Consider serializing snapshot git operations + cleanup via an in-process lock (similar to FileTime.withLock) or skipping tmp-pack deletion when a gc/repack lock is present (e.g., gc.pid / objects/pack/*.lock).
Summary
Fixes #471