chore(scripts): add setup-worktree.sh with copy-on-write node_modules - #388
chore(scripts): add setup-worktree.sh with copy-on-write node_modules#388kkohtaka wants to merge 1 commit into
Conversation
Worktrees under .claude/worktrees/ were filling the disk: the checkout itself is ~3MB since git objects are shared, but `npm ci` in each one costs ~424MB, so a handful of accumulated worktrees reached 858MB. On APFS, `cp -c` clones the main checkout's node_modules copy-on-write, sharing blocks until npm rewrites a file. Measured on a fresh worktree: 5.2s and 8.6MB of real disk, against ~90s and 424MB for `npm ci`. The script bases new branches on origin/master per the branch rules, resolves the main checkout via --git-common-dir so it works when invoked from inside another worktree, and reruns `npm install` only when the branch's lockfile differs from the main checkout's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
✅ Terraform Plan (Staging) SUCCESS📊 View full plan output in the workflow run Auto-triggered after Test workflow success |
|
Closing: this addresses the wrong code path. The worktrees that actually fill the disk are created by Claude Code itself — there are 41 The measurement stands ( |
Summary
.claude/worktrees/were filling the disk. The checkout itself is only ~3MB (git objects are shared with the main repo), butnpm ciin each worktree costs ~424MB — a handful of accumulated worktrees had reached 858MB against 15GB of free space.scripts/setup-worktree.shcreates a worktree and populatesnode_moduleswithcp -cinstead, which on APFS clones it copy-on-write: blocks stay shared until npm rewrites a file. Measured on a fresh worktree: 5.2s / 8.6MB of real disk, against ~90s / 424MB fornpm ci.npm run setup:worktree -- <name> [branch].Behavior notes for reviewers:
origin/masterafter agit fetch, per the branch rules inCLAUDE.md; an existing branch name is checked out as-is.--git-common-dir, so the script works when invoked from inside another worktree (where.gitis a file).npm installreruns only when the branch'spackage-lock.jsondiffers from the main checkout's. Note thatnpm ciwould defeat the clone entirely, since it deletesnode_modulesbefore reinstalling.Test plan
npm testinside the created worktree — 48 tests passed, so the clonednode_modulesis functional.autonyan-shared -> ../src/shared) andnode_modules/.bin/*survive the clone as relative links, and thatrequire.resolve('autonyan-shared')resolves into the new worktree rather than the main checkout.dfbefore/after (8.6MB) rather thandu, which reports the full 434MB for CoW clones.npm run lint, the read-only formatting checks, andnpm run test:coverageall pass.shfmt -d scripts/*.shwas verified separately viago runsince shfmt is not installed locally;tflintcould not be run locally either, but this PR changes no Terraform.🤖 Generated with Claude Code