Checkout strategy is the quiet multiplier behind every macOS pipeline: the same Mac mini M4 can feel “fast enough” with git worktree or “mysteriously flaky” when DerivedData leaks between jobs. In 2026, teams that publish an explicit worktree vs clean-clone policy reduce queue time and audit risk. This guide gives two matrices, numeric disk budgets, eight rollout steps, and FAQ structured data you can paste into internal runbooks.
Pair this policy with disk & artifact retention, capacity envelopes, and runner affinity rules. When you need additional dedicated hosts in Hong Kong, Japan, Korea, Singapore, or the United States, start from pricing and keep help open for SSH/VNC access patterns.
Why checkout mode is a scheduling problem, not just Git trivia
Self-hosted macOS runners are stateful by default: global caches, user-level Keychain items, and Xcode’s default DerivedData location survive across jobs unless you fence them. A clean clone per job isolates Git objects but does not automatically isolate compilers. Worktrees share a single object database—fast—but amplify any mistake in cleanup scripts. Treat checkout mode as part of your blast-radius story alongside secrets and signing identities.
- Worktrees minimize
git fetchbytes when many branches build on the same revision stream. - Clean clones maximize isolation when repositories run post-checkout hooks that mutate tooling outside the tree.
- Hybrid patterns (warm bare mirror + ephemeral worktrees) are common at scale but require strict path conventions.
Decision matrix A: pick worktree, clean clone, or hybrid
| Repository signal | Recommended mode | Watch-out |
|---|---|---|
| Monorepo, high churn, shared Xcode version | Hybrid (bare mirror + worktrees) | Must pin DerivedData with -derivedDataPath per worktree |
| Small app, few dependencies, needs reproducibility | Clean clone per job | Watch LFS bandwidth; cache blobs on host with checksum verification |
| Release signing with hardware-bound identities | Dedicated host + clean clone | Never share a worktree base with untrusted forks |
| Forked pull-request builds from external contributors | Ephemeral clone in unique path | Disable shared bare mirrors across trust boundaries |
Decision matrix B: cache placement vs leakage risk
The checkout mode chooses where Git objects live; cache placement chooses what survives the next job. Align both decisions or you will “clean clone” yet still leak compiler state through global paths.
| Cache | Safe default on M4 runners | Leakage symptom |
|---|---|---|
| Swift Package Manager | Per-job SourcePackages under workspace temp |
Version skew across PRs when global cache reused without lockfile hash |
| CocoaPods / Bundler | Vendor inside clone or content-addressed tarball cache | Native extension builds picking wrong architecture flags |
| Xcode DerivedData | Always path-scoped per job ID | Flaky UI tests after partial index from another branch |
Executable disk budgets (starting points)
- Bare mirror ceiling: keep monorepo mirrors under 120 GB on 512 GB hosts; prune with audited scripts, not manual deletes.
- Concurrent worktrees: cap at 4 per host unless IO metrics show sustained read throughput headroom.
- Clean clone scratch: reserve 2× largest expected working tree for
git clone --depth 1plus LFS peaks. - Alarm: page when free disk on CI volume drops below 15% for more than 5 minutes.
Audit note: document which trust tier each runner group belongs to. A worktree base that ever checked out a forked PR should not later build signed release artifacts without a documented wipe.
Eight rollout steps
- Classify repos into trusted internal, partner, and public-fork tiers.
- Measure p95 checkout+compile time for each tier under both modes for one sprint.
- Implement path conventions such as
/ci/jobs/<id>/treethat automation owns exclusively. - Wire post-job hooks that remove worktrees, DerivedData, and simulator caches tied to the job ID.
- Block global caches unless keyed by content hash + trust tier.
- Add metrics for checkout seconds, LFS megabytes, and disk free percent per host.
- Game-day a disk-full scenario twice per quarter.
- Scale hardware when budgets force risky sharing—NodeMac can add dedicated Mac mini M4 nodes per region without colo lead times.
FAQ
When is git worktree safe on shared Mac mini M4 CI hosts?
When each worktree path is isolated per job, hooks are controlled, submodules are pinned, and cleanup removes both the worktree and any co-located caches. Do not share a bare repo with interactive developer sessions.
Why do clean clones still fail randomly?
Usually global caches, LFS network issues, or scanners touching outputs. Scope caches per job and correlate failures with network graphs.
How much extra disk for parallel worktrees?
Budget one working tree plus shared object store per concurrent worktree, plus per-job DerivedData if compiling Xcode projects.