Git Worktree
npx skills add marcusrbrown/systematic --skill git-worktreeGit Worktree Manager
Section titled “Git Worktree Manager”scripts/worktree-manager.sh creates, lists, switches and cleans up worktrees. Every worktree lands at .worktrees/<branch> under the main repository root, from any subdirectory or from inside another worktree. Nested names work: feat/x lands at .worktrees/feat/x.
- A named location or tool wins. If the user, a project instruction, or another loaded skill or config names a different location or tool, follow it and skip the script. Read the repo’s
AGENTS.mdand any other project instruction file for one before you create. - Otherwise never use raw
git worktree add, a sibling directory,/tmp, or a path inside another worktree. - Refused layout. Exit 3
unsupported-layoutmeans a bare repository,core.bare, a separate git directory or a submodule. Report it and ask for a location or tool. Run rawgit worktree addonly with the user’s approval. - Skip worktrees for small or read-only work. Fix a typo in place. Read a file from another branch with
git show <branch>:<path>.
Commands
Section titled “Commands”SKILL_DIR="<skill directory stated when this skill loads>";bash "$SKILL_DIR/scripts/worktree-manager.sh" <command>A worktree’s name is its path under .worktrees/, for example feat/x. Run help for the full usage.
| Command | Effect |
|---|---|
create <branch> [--base <ref>] | New branch from origin/<default branch>, fetched first. Prints branch=, base= and, last, path=. |
list | One line per worktree. |
switch <name> | Prints the path and nothing else. |
copy-env [<name>] | Copies git-ignored .env* files; never overwrites. |
cleanup | Report only. |
cleanup --remove <name>... | Removes the named clean worktrees. |
Exit codes: 0 ok, 1 error, 2 usage, 3 refused. Errors print error: <code>: <message> on stderr. The script never reads stdin.
On exit 3, report the error and ask. Never retry with --force, rm -rf, another path or another name.
base-unresolved: ask the user which base to use with--base. Never assumemain.branch-exists,target-exists: report it, with the printed path, and ask. Never delete the directory.
After create
Section titled “After create”- Use the printed
path=as the workdir for every later command, and as the workspace root you give subagents. Never assume acdpersisted.switchcannot change your directory. - A new worktree has no installed dependencies. Install them there before running tests.
- The new branch has no upstream. Publish it with
git push -u origin <branch>.
Reviewing a PR
Section titled “Reviewing a PR”Run git fetch origin +refs/heads/<pr-branch>:refs/remotes/origin/<pr-branch>, then create review/<n> --base origin/<pr-branch>. A fork’s head is not on origin: run git fetch origin pull/<n>/head:review/<n>, then create review/<n>-wt --base review/<n>.
Cleanup
Section titled “Cleanup”- Run
cleanup. Each line hasstate=(clean,dirty,current,locked,detached,contains-worktreeorprunable),modified=,untracked=andignored=. - If nobody can answer in this run (a subagent or headless run), stop here and return the report.
- Removal deletes a worktree’s ignored files, such as copied
.envfiles andnode_modules. Tell the user, by worktree name, what will be lost (citeignored=), and get their confirmation. A blanket “nuke them all” or “don’t ask” does not waive this. - Run
cleanup --remove <name>...with confirmed names only. Exit 3 means a removal was refused: report itsreason=. - Dirty and every other non-
cleanworktree is reported, never forced. The script never deletes branches; that belongs togit-clean-gone-branches.