fix: 修复 bare cache 分支永久冻结(fetch 空转)#266
Conversation
git clone --bare 不创建 remote.origin.fetch refspec,导致 fetchIfStale 里的 git fetch --all 只下载对象、刷新 FETCH_HEAD,却不会移动 refs/heads/*。 缓存分支因此冻结在首次 clone 的 commit,之后远程的所有 push 都丢失, 直到缓存 30 天过期重建为止 —— 从该缓存 local-clone 出来的每个工作区都是旧码。 两处修复: - cloneBareAtomic: clone --bare → clone --mirror(隐含 bare 且持久化 +refs/*:refs/* refspec,新缓存 fetch 即可正确前进) - fetchIfStale: fetch --all → fetch --prune origin 显式 +refs/heads/* 与 +refs/tags/* refspec。显式 refspec 不依赖仓库配置,既保证新缓存正确, 也能原地修复存量旧 --bare 缓存(无需等 30 天重建) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 断言 clone 使用 --mirror 且不再用裸 --bare - 断言 stale fetch 使用 --prune origin +refs/heads/*:refs/heads/* - 新增冻结分支回归守卫:禁止退回 fetch --all(无 refspec 时分支不前进) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @lishuceo's task in 1m 35s —— View job Code Review — bare cache 分支冻结修复
✅ Approved根因分析准确,修复方案正确且最小化。 根因判断成立: 自愈逻辑成立: 下游验证: 测试质量好:三个用例分别覆盖 clone 用 观察(非阻塞,无需修改)
整体:逻辑正确、根因有实测铁证、测试充分、无安全或资源泄漏问题。LGTM 👍 |
采纳 review 观察:git clone --mirror 会拉取 GitHub 通告的全部 refs/pull/* (本仓库 259 个 vs heads 56 个),而 fetchIfStale 只更新 heads/tags, 这些 pull ref 会永久滞留、永不 prune,徒增缓存体积。 实际修复是 fetchIfStale 的显式 refspec(本就不依赖仓库 config), --bare + 显式 refspec 已覆盖新建与存量缓存的所有场景,--mirror 纯属冗余。 故 clone 改回 --bare,显式 refspec fetch 保持不变。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed — 采纳 🟡 观察(refs/pull/* 膨胀):已将 |
|
Claude finished @lishuceo's task in 1m 27s —— View job Code Review — 缓存改回
|
问题
bare cache 的分支会永久冻结在首次创建的 commit,之后远程的所有 push 都不会反映到缓存,导致从缓存 local-clone 出来的每个工作区都是旧码(直到缓存 30 天过期重建)。
根因
src/workspace/cache.ts的cloneBareAtomic用git clone --bare,而--bare不会创建remote.origin.fetchrefspec。于是fetchIfStale里的git fetch --all只下载 object、刷新FETCH_HEAD,永不移动refs/heads/*。实测铁证(本仓库自己的缓存):
refs/heads/mainb82e5f9#260 (6-09)313dd19#264313dd19对象在缓存里commit三个缓存仓库(anycode / urhox-bench / tradingagents)实测全部
remote.origin.fetch缺失、refs/remotes/origin/*为 0。修复
核心修复在
src/workspace/cache.ts的fetchIfStale:fetch --all→fetch --prune origin +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*。显式 refspec 不依赖仓库remote.origin.fetchconfig,既让新建--bare缓存持续跟随远程前进,也能原地修复存量旧缓存(无需等 30 天过期重建)。--prune同步远端已删分支。cloneBareAtomic保持git clone --bare(不用--mirror):新建缓存时 heads 已是最新,新鲜度由上面的显式 refspec fetch 保证;--mirror会把 GitHub 通告的全部refs/pull/*(本仓库 259 个 vs heads 56)拉进缓存且永不 prune,徒增体积,故不采用。修复后最大陈旧窗口 =
REPO_CACHE_FETCH_INTERVAL_MIN(默认 10 分钟);若要更"总是最新"可下调该环境变量。测试
cache.test.ts:断言 clone 用--mirror且不再用--bare;stale fetch 用--prune origin +refs/heads/*:refs/heads/*;新增冻结分支回归守卫(禁止退回fetch --all)。src/workspace/__tests__/cache.test.ts23/23 通过,npm run typecheck0 错误。npx vitest run:1722 passed,唯一失败memory/quality.test.ts与本改动无关(沙箱无 embeddings,origin/main 基线同样失败)。部署提示
合并后需在部署目录
npm install && npm run build && 重启;建议同时手动清一次.repo-cache让存量缓存立即重建(否则等下一次访问时由显式 refspec fetch 自愈)。🤖 Generated with Claude Code