worktree
GitHub管理 Git worktree 以支持并行构建和测试。提供一键创建、共享 Cargo 缓存及清理工作区的标准化脚本,确保主分支稳定并优化构建性能。
Trigger Scenarios
Install
npx skills add nubjs/nub --skill worktree -g -y
SKILL.md
Frontmatter
{
"name": "worktree",
"metadata": {
"internal": true
},
"description": "Create and manage isolated git worktrees for parallel build\/test\/landing work on the nub repo. Invoke (via the Skill tool) whenever you need a fresh worktree to land a change, when you want to know what `.worktreeinclude` does or how to add an entry, or when cleaning up after a merge. Encodes the one-command setup (`nub scripts\/new-worktree.ts <slug>` or `node …`) that bakes in the proven recipe — worktree off origin\/main (vendor\/aube is plain in-tree files now, no submodule init), the shared CARGO_TARGET_DIR (`~\/.cache\/nub\/shared-target`) that all worktrees reuse, and applying `.worktreeinclude` — plus the eagerly-pull-the-shared-tree discipline and the safe cleanup path. Pairs with the `dev-loop` build skill."
}
Worktrees for parallel nub work
Substantive nub-repo work lands via a PR opened from an isolated git worktree; the shared working tree stays on main and is never branched, reset, or stashed. The whole setup is one command — don't hand-roll the git worktree add + target-dir recipe.
Create a worktree
The script runs under both nub (dogfood) and plain Node:
nub scripts/new-worktree.ts <slug>
node scripts/new-worktree.ts <slug>
It performs the proven recipe, in order:
git fetch origin(skip with--no-fetch).git worktree add ~/.cache/nub/worktrees/<slug> -b <slug> origin/main— tracked files only; the shared tree is untouched.vendor/aubeis plain in-tree files, checked out by this step with no submodule init. (Non-temp location: not auto-swept like/tmp, out of the repo dir, same volume so APFS clonefile stays fast.)- Apply
.worktreeinclude— copy/symlink the listed gitignored entries in. - Pre-create + print the shared
CARGO_TARGET_DIR(~/.cache/nub/shared-target).
Options: --base <ref> (default origin/main), --path <dir> (default ~/.cache/nub/worktrees/<slug>), --no-fetch, --help.
Then build through the wrapper — do not export CARGO_TARGET_DIR yourself; scripts/rust-build.sh picks the right dir and CoW-seeds an isolated one when this worktree diverges a depended-on crate (see the rust-build skill):
cd ~/.cache/nub/worktrees/<slug>
scripts/rust-build.sh build -p nub-cli --profile fast
All worktrees share ONE target dir (~/.cache/nub/shared-target), so a second worktree reuses the crates.io dependency artifacts another already compiled and recompiles only the ~10 workspace crates — one target dir instead of ~30 multi-GB private ones. Tradeoff: cargo locks the target dir during a build, so two sharing worktrees serialize. Don't clean the shared dir between iterations. Build loop, profiles, and crate map: the dev-loop skill.
.worktreeinclude — bringing gitignored things in
git worktree add checks out tracked files only, so a worktree is lean by default (no target/, node_modules/, .repos/). .worktreeinclude at the repo root lists the gitignored things a worktree still needs; the script copies or symlinks each in.
Format — one entry per line, # comments and blank lines ignored:
[copy|symlink] <path> # path is relative to the repo root, both sides
The verb is optional and defaults to copy; use symlink for large read-only things. Sources are read from the MAIN working tree even when you run the script from inside another worktree.
The shipped default symlinks .repos/ (read-only reference checkouts of Node, Bun, pnpm, …). Do NOT add target/ — the shared CARGO_TARGET_DIR is the build cache; an in-worktree target/ is exactly the disk bloat the shared dir avoids.
Eagerly pull the shared tree
The shared tree drifts behind origin/main because every landing goes worktree → push → merge and nothing pulls it back. After merging any PR or pushing to origin:
git -C <shared-tree> fetch origin && git -C <shared-tree> merge --ff-only origin/main
Never git pull --ff-only here. This repo sets pull.rebase=true, so pull runs rebase's precondition check first and aborts with cannot pull with rebase: You have unstaged changes on ANY dirty file — and the shared tree always carries some agent's WIP, so that form fails 100% of the time. merge --ff-only has no clean-tree precondition; it refuses only if the incoming commits would overwrite a locally-modified file.
Corollary: do NOT commit directly in the shared tree's checkout — a direct commit makes it diverge rather than merely fall behind, and a diverged tree cannot be fast-forwarded at all. If you take the sanctioned docs/control-surface exception, sync immediately before committing and push in the same breath; never rest with an unpushed commit there. This keeps files current; loaded .claude/ hooks still need a session restart.
Clean up after a merge
git worktree remove ~/.cache/nub/worktrees/<slug> --force # leave ~/.cache/nub/shared-target in place
--force discards the worktree even with build artifacts present — so push your work first; anything uncommitted is thrown away. Do NOT delete ~/.cache/nub/shared-target — it's the warm cache the next worktree builds against.
Remove ONLY the EXACT worktree path you own — never hunt for one by HEAD SHA. If the stated path does not exist, STOP and report "nothing to clean." Sibling worktrees routinely share a HEAD (two branches cut from the same base, a stacked branch off another's head), so SHA-matching deletes a different agent's active worktree and --force-discards its uncommitted WIP. A dispatch prompt with a cleanup step must name the exact path and add: "remove only this path; if absent, report and stop — never match by SHA."
There is also an older bash helper, scripts/worktree.sh (worktrees under .worktrees/, branched off LOCAL main, with rm/list/reap subcommands and uncommitted/unpushed-work safety checks). new-worktree.ts is the preferred entry for landing work; reach for worktree.sh reap to prune stale dead-session worktrees.
Version History
-
46280a5
Current 2026-08-03 01:44
将共享树的同步命令从 git pull --ff-only 改为 git merge --ff-only,解决因 rebase 前置检查导致的失败问题,确保在脏树状态下能正确更新共享树。
- 4fd083f 2026-07-19 12:03
-
ab079b4
2026-07-11 18:57
修复清理逻辑:移除通过 HEAD SHA 搜索 worktree 的行为,改为仅删除精确匹配的路径,确保清理操作准确无误。
- 44d0dd0 2026-07-05 11:03


