多仓库并行 PR 压在同一台高内存 Apple Silicon裸金属上时,检出策略往往在「git worktree 共享对象库」与「每 Job 独立 clone」之间摇摆:前者省磁盘与二次检出时间,后者隔离干净、排障路径短。下文按检出时延、NVMe 峰值、依赖缓存复用三条线对照,并链 大仓库冷启动与 blobless/shallow 姊妹篇、Bazel/Gradle 远程构建与 NVMe 分区。
一、机制对照:worktree 与独立 clone 各吃掉什么
git worktree add 在同一主仓库下挂多份工作树,.git/objects 只保留一份;每 Job 独立 git clone 则各自携带完整对象库与 refs。并行几十个轻量 PR 时,worktree 通常把首包后的增量检出压到「树 diff + 索引更新」为主;独立 clone 仍受pack 解包与写盘带宽约束,但子模块、LFS、凭据改写互不串味。
合规视角下,「每 PR 独立系统用户 + 独立 $CI_PROJECT_DIR」往往更偏好clone + 用完即毁;若坚持 worktree,须把对主库 .git/config、hooks 的写入封进只读层,并在审计里记录共享对象库的归属与备份周期。高内存节点上也可预热:镜像机先做一次完整 fetch,再由调度器并行派发 worktree add,把冷启动从单队列里剥离。
二、检出时延:何时 worktree 真的更快
首次 cold path 两者都要拉对象;从第二次起,若对象已在页缓存或本地 bundle,worktree 往往能把「分钟级」拉到「数十秒」量级(仍取决于 mono-repo 体量与 LFS)。若 Runner 每次 Job 都换干净 $CI_BUILDS_DIR 且不做持久化 .git,worktree 优势会被反复 fetch抵消——此时应回到 shallow、blobless 与 CDN 镜像,并对 fetch 做按分支深度与 refspec 收敛。
三、磁盘峰值:N 份树 vs N 份对象
粗略记账:N 个 worktree ≈ N 份工作树 + 1 份 objects;N 次完整 clone ≈ N ×(objects + refs)。在 NVMe 上并行展开大量 pack 时,瞬时写队列深度飙升会拖慢同机的 xcodebuild 与模拟器镜像解压。高统一内存机型 page cache 友好,但I/O 争用仍会出现「CPU 不饱和、总线抖」——要给 worktree 数与 clone 并发设硬上限,并把 git config gc.auto 与定时 git maintenance 写进基线镜像。
四、依赖缓存复用:worktree 不会自动共享 DerivedData
Git 层复用与 Xcode/npm 层复用解耦:DerivedData、CocoaPods、SwiftPM、Gradle 用户缓存需单独用只读挂载 + 每 PR 可写 overlay 或路径前缀矩阵。推荐在脚本里显式 -derivedDataPath 指向共享卷上的「只读基线 + 可写层」,避免多 worktree 默认写用户目录导致锁文件与 ModuleCache 踩踏。Bazel/远端缓存键与磁盘分区实践见上文姊妹链。
五、落地 FAQ(节选)
- 能混用吗?常见是黄金镜像上保留主库 + 若干 worktree,长尾或高风险 Job 仍 fallback 到 ephemeral clone。
- 需要全局锁吗?多 worktree 并发
fetch同一远端时,建议 Runner 侧串行化或分片 ref,减少 pack 竞态与「幽灵」索引。 - 清理策略?Job 结束
git worktree remove --force并删孤儿目录;clone 模式用 APFS 克隆卷或 tmpfs 前缀降低 rm 成本。
在 Mac mini 上把「检出 + 编译」基线跑稳
上述策略最终都落在稳定 I/O、足够内存带宽与可预期的 Xcode 环境上:Apple Silicon 统一内存适合并行多 worktree 与模拟器;macOS 与 Xcode 同厂集成减少跨栈排障;Mac mini M4 待机约 4W、静音适合无人值守 Runner;Gatekeeper、SIP、FileVault 降低长驻节点的恶意面。若你正为高内存裸金属节点选型,Mac mini M4 仍是 2026 年高性价比起点——打开 Macstripe 首页 即可按需开通独占云 Mac,把 worktree 与缓存分区先在单机验证再扩池。