anthropics / anthropics/claude-code
[BUG] Desktop (macOS): background full checkout of pooled worktrees is unthrottled — 3 concurrent on an 82k-file repo take 11-13 min each (24 s median), git status times out, pool grows to 72 GB
- 主要言語
- Python
- スター
- 145k
- フォーク
- 23.1k
- PR マージ指標
- PR 指標を取得中
説明
## Summary
The desktop app populates every new pooled worktree with a "background full checkout" (`git checkout HEAD -- . :(exclude).claude`, the same staged-checkout machinery described in #91443). On a large repository these checkouts are neither serialized nor throttled. When three sessions started within four minutes and the pool had no reusable worktree, the three concurrent full checkouts of ~82k files took **11 to 13 minutes each** (the same step normally takes ~24 s on this machine), the app's own `git status` timed out 57 times in that window, and an unrelated `git add` in the main working tree stalled for 888 s. Nothing in the UI shows that any of this is happening. Two days of normal use left 11 pooled worktrees on disk, 72 GB.
This is a macOS throughput/visibility report, not a correctness one: the checkouts complete and the main working tree is never touched.
## Environment
| | |
|---|---|
| Claude desktop app | 1.44121.2 (macOS) |
| Claude Code (bundled CLI) | 2.1.258 / 2.1.259 |
| OS | macOS 26.6.2 (Darwin 25.6.0, arm64), APFS |
| Git | 2.50.1 (Apple Git-155), invoked by the app as `/Applications/Xcode.app/Contents/Developer/usr/bin/git` |
| Repo | one main clone, 81,863 tracked files (`git ls-files | wc -l`), no remote |
| Worktree toggle | off (`tengu_worktree_mode: false` in `~/.claude.json`); worktrees are still created for spawned tasks / new sessions when the pool has no reusable candidate (`[WorktreePool] No reusable worktree … (N/N candidates checked)`) |
| Pool on disk | `.claude/worktrees/`: 11 worktrees, 72 GB (`du -sh`) |
| Session mix | 8-12 concurrent desktop sessions |
## Measurements (from `~/Library/Logs/Claude/main.log` and the rotated `main1.log`; repo path redacted as ``)
Every `[stageCheckout] Background full checkout done in …` line for this repo between 2026-09-02 and 2026-09-04:
| n | min | median | max |
|---|---|---|---|
| 28 | 14.5 s | 23.7 s | 785.1 s |
The three worst values are the three that ran concurrently:
```
2026-09-04 04:13:48 [info] [WorktreePool] No reusable worktree for (3/3 candidates checked)
2026-09-04 04:13:48 [info] Creating worktree for session local_b157b6d6-… from
2026-09-04 04:13:49 [info] [stageCheckout] Selective checkout done in 226ms (2 paths)
2026-09-04 04:15:44 [info] [stageCheckout] Selective checkout done in 6883ms (2 paths)
2026-09-04 04:17:57 [info] Creating worktree for session local_8f8a1172-… from
2026-09-04 04:18:01 [info] [stageCheckout] Selective checkout done in 1192ms (2 paths)
2026-09-04 04:26:54 [info] [stageCheckout] Background full checkout done in 785122ms
2026-09-04 04:27:57 [info] [stageCheckout] Background full checkout done in 733513ms
2026-09-04 04:29:00 [info] [stageCheckout] Background full checkout done in 658981ms
```
Process table at 04:21 (parent 798 = `/Applications/Claude.app/Contents/MacOS/Claude`), trimmed:
```
PID PPID ELAPSED STAT COMMAND
48993 798 08:20 R …/git -c core.hooksPath=/dev/null -c safe.directory=* -c core.fsmonitor=false -c branch.autoSetupMerge=false -c core.longpaths=true checkout HEAD -- . :(exclude).claude
50325 798 06:25 R …/git … checkout HEAD -- . :(exclude).claude
51765 798 04:08 R …/git … checkout HEAD -- . :(exclude).claude
```
Collateral in the same window (04:13 to 04:30):
- 57 × `[GitStatusService] Failed to check git status: git status timed out { code: 'EGITTIMEDOUT' }` (142 for the whole day).
- The stage-1 selective checkout itself degraded from 40-230 ms to 6,883 ms while the other full checkouts were running.
- A `launchd` job doing `git add -A` in the main working tree held `.git/index.lock` for 888 s with ~5 s of CPU (I/O wait); 1-minute load average 30-69. It normally finishes well under 2 minutes (29 later runs, max 109 s).
Uncontended, each new worktree still costs 15-80 s of full checkout on this repo plus roughly 6.5 GB of disk; the pool grew to 11 worktrees / 72 GB between 2026-09-02 22:04 and 2026-09-04 14:07 with no indication anywhere in the UI.
## Expected
- Serialize, or cap at one or two, the background full checkouts per base repository and queue the rest. On a saturated disk three concurrent checkouts of the same tree are much slower than three sequential ones (here 3 × ~12 min vs 3 × ~25 s).
- Don't stack more parallelism on top: #92019 reports `checkout.workers=8` being forced since 2.1.260, which on an already saturated disk goes the wrong way.
- Consider populating a new pooled worktree from an idle pooled worktree with an APFS clone (`cp -c` / `clonefile`), which is near-instant and takes no extra space until files diverge, instead of a full checkout from the object store.
- Show the user that a worktree is being prepared, and expose pool size and disk usage with a way to cap or prune the pool.
## Steps to reproduce (what we did)
1. Repository with tens of thousands of tracked files and several GB of content (ours: 81,863 files).
2. Start three spawned-task or new sessions within a couple of minutes so the pool has no reusable worktree.
3. Compare `grep 'Background full checkout done' ~/Library/Logs/Claude/main.log` against a single uncontended creation, and count `EGITTIMEDOUT` in the same window.
Related: #91443 (same staged-checkout machinery; Windows CRLF), #92019 (`checkout.workers=8` regression; Windows), #91973 (worktree teardown; Windows), #75911 (pool re-lease; macOS). Happy to share the full log excerpts or test a build.
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
No source files are named. Start with the [WorktreePool] and [stageCheckout] entries in ~/Library/Logs/Claude/main.log and main1.log, then reproduce three concurrent pooled-worktree creations on a large repository and compare checkout times with EGITTIMEDOUT counts. Done means checkout concurrency is controlled and the UI exposes preparation and pool or disk usage clearly.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- git, macos
- 領域
- desktop, performance, tooling
- issue の種類
- バグ
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100