fix(server): clean status fetch temporary packs#4338
Conversation
- Track temporary pack files that exist before each status refresh. - Remove only new tmp_pack files when the refresh times out or fails. - Add focused regression coverage for preserving pre-existing pack files.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR rewrites the status fetch mechanism with significant new logic for isolated object directories and cleanup. Multiple unresolved review comments identify potential bugs including orphaned directories (high severity) and incorrect refspec handling (medium severity), warranting human review. You can customize Macroscope's approvability policy. Learn more. |
- Replace operation-scoped pack deletion with a one-hour stale-file grace period. - Run best-effort cleanup before fetches and in an interruption-safe finalizer. - Cover active, stale, completed, and unknown-mtime pack entries.
- Fetch upstream status into a per-operation object store and temporary ref. - Remove failed or timed-out fetch objects immediately without touching concurrent Git work. - Promote complete pack and loose objects before atomically updating the tracking ref. - Verify successful refreshes leave no temporary refs or object directories.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 46ac662. Configure here.
| fetchedCommit, | ||
| expectedTarget, | ||
| ]); | ||
| }).pipe(Effect.ensuring(cleanupIsolatedFetch)); |
There was a problem hiding this comment.
Orphaned fetch dirs never reaped
High Severity
The new isolated status-fetch mechanism creates temporary directories under objects/t3-status-fetch/. Its cleanup is best-effort (Effect.ignore) and lacks a stale-reaping mechanism for these new directories, unlike the legacy tmp_pack_* files. This can leave behind accumulated directories if cleanup fails, leading to disk space exhaustion.
Reviewed by Cursor Bugbot for commit 46ac662. Configure here.
| "--no-write-fetch-head", | ||
| "--refmap=", | ||
| remoteName, | ||
| `+refs/heads/${branchName}:${temporaryRef}`, |
There was a problem hiding this comment.
Wrong remote refspec assumed
Medium Severity
The new status fetch builds +refs/heads/${branchName}:… from the remote-tracking shorthand. That assumes a 1:1 refs/heads/* mapping, unlike the previous git fetch <remote> which honored configured refspecs, so custom upstreams (for example pull-request refs) can fail to refresh and leave behindCount stale.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 46ac662. Configure here.
| "--no-write-fetch-head", | ||
| "--refmap=", | ||
| remoteName, | ||
| `+refs/heads/${branchName}:${temporaryRef}`, |
There was a problem hiding this comment.
Default-branch tip goes stale
Medium Severity
Status refresh now fetches only refs/heads/${branchName} into a temporary ref, instead of refreshing the whole upstream remote. On a feature branch, aheadOfDefaultCount still compares against local origin/main (via computeAheadCountAgainstBase), so that metric can stay wrong until some other full fetch updates the default remote-tracking tip.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 46ac662. Configure here.


What Changed
Why
A status refresh that exceeded the five-second timeout could leave a full temporary pack behind every polling cycle, eventually filling the disk.
Closes #4296
Checklist
Note
Medium Risk
Changes core Git object/ref handling for background status fetches; incorrect promotion or ref updates could corrupt remote-tracking state, though CAS update-ref and ensuring cleanup limit blast radius.
Overview
Replaces the simple background
git fetchused for status upstream refresh with an isolated fetch so interrupted or timed-out polls no longer leave largetmp_pack_*files in the shared.git/objects/packdirectory (fixes disk growth from repeated 5s timeouts).Each refresh fetches into a per-operation directory under
objects/t3-status-fetch/<uuid>viaGIT_OBJECT_DIRECTORY/ alternates, fetches only the upstream branch into a temporary ref underrefs/t3-status-fetch, then on success promotes packs and loose objects into the real object store and updates the remote-tracking ref with a compare-and-swapupdate-ref. Temporary refs and directories are always torn down inEffect.ensuring.Before starting a fetch, legacy
tmp_pack_*entries in the shared pack dir older than one hour are removed via exportedisStaleGitTemporaryPackFile. The status refresh cache key now includesbranchName. Tests cover the stale-pack helper and assert no leftover isolated fetch artifacts after a successful remote status refresh.Reviewed by Cursor Bugbot for commit 46ac662. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix status fetch to use isolated object directories and clean up stale temporary pack files
fetchRemoteForStatusnow performs fetches into a per-operation isolated object directory (objects/t3-status-fetch/<uuid>) with a temporary ref, then promotes fetched objects into the main store and atomically updates the remote-tracking ref before cleaning up.tmp_pack_*files older than 1 hour in the shared pack directory are opportunistically removed before each fetch.StatusRemoteRefreshCacheKeyis expanded to includebranchName, so cache entries are now per-branch rather than shared across branches.isStaleGitTemporaryPackFileutility to identify stale temporary pack files by prefix and mtime.Macroscope summarized 46ac662.