dist/codex/plugins/dev-tools/skills/using-git-worktrees/SKILL.md
Creates isolated git worktrees for parallel development. Use when starting feature work needing isolation or working on multiple branches simultaneously. Not for simple branch switching or basic git operations.
npx skillsauth add alexei-led/claude-code-config using-git-worktreesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Main repo stays on main/master — never edit directly. Every branch gets its own worktree. All worktrees for a project live under one per-project root directory, <project>.worktrees/, a sibling of the main repo. Delete the worktree and its branch after the PR merges.
Think of a worktree as a disposable branch folder, not a long-lived parallel environment.
Exception: Trivial one-liner commits on a solo project can go directly on main to avoid ceremony overhead.
Check repo state before creating a worktree. Any worktree workflow description must name this dirty-state check before git worktree add:
git status --short
git branch --show-current
git worktree list
If the current worktree is dirty, ask whether to commit, stash, or create the new worktree anyway before proceeding. Confirm before running cleanup commands that remove worktrees or delete branches.
The per-project root is derived from the main worktree, so create and clean up correctly even when invoked from inside another worktree:
# main worktree is always the first entry of `git worktree list --porcelain`
main_wt=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
project=$(basename "$main_wt")
root="$(dirname "$main_wt")/$project.worktrees"
# 1. Create worktree for new work (slug = branch with / → -)
mkdir -p "$root"
git worktree add "$root/fix-cron" -b fix-cron
# 2. Work there (open editor/Claude Code in that folder)
cd "$root/fix-cron"
# 3. After PR merges — confirm, then clean up from the main worktree
scripts/cleanup-worktree.sh fix-cron
Both steps are scripted: scripts/setup-worktree.sh <branch> [base] and scripts/cleanup-worktree.sh [branch].
All worktrees for a project live under one root, <project>.worktrees/, a sibling of the main repo (never nested inside it):
~/projects/
├── myproject/ # main worktree — always on main, always clean
└── myproject.worktrees/ # per-project worktree root
├── fix-cron/ # worktree for fix-cron branch
├── feature-auth/ # worktree for feature/auth branch
└── bugfix-123/ # worktree for bugfix/issue-123 branch
Why a sibling root: one tidy place per project, no .gitignore pollution, clean git status, independent build artifacts. The root is removed automatically once its last worktree is cleaned up.
Worktree dir is the branch slug only — slashes become dashes. No project prefix; the <project>.worktrees/ root already scopes it.
fix-cron — myproject.worktrees/fix-cronfeature/auth — myproject.worktrees/feature-authbugfix/issue-123 — myproject.worktrees/bugfix-issue-123When a PR merges, remove the worktree and delete its branch. State clearly what is being removed and why before running anything destructive.
Squash and rebase merges rewrite the commit, so git branch -d reports the branch as "not fully merged" even though the PR is merged. The source of truth is the PR state, not local ancestry — do not conflate them.
Use scripts/cleanup-worktree.sh [branch]. It is strict by default: unless gh confirms the PR is MERGED it changes nothing and exits with a single clear message. Pass --force to proceed anyway — when gh is not installed (you confirm the merge) or to abandon an unmerged branch on purpose; --force also force-removes a dirty worktree and force-deletes the branch. It defaults to the current worktree's branch, refuses to remove the main worktree, cds out of the worktree before removing it, falls back to git branch -D for the squash/rebase case, runs git fetch --prune, and prunes the empty root. It does not run git pull — pull main yourself afterward only once you have confirmed main is checked out and clean. WORKFLOW.md has the manual command sequence for when the script is unavailable.
git worktree add "$root/<slug>" <branch> (no -b) to check it out.git worktree remove fails with "is dirty": confirm with user before running git worktree remove --force.git branch -d says "not fully merged" after a squash/rebase PR merge: confirm the PR is MERGED, then use git branch -D — this is expected, not data loss.cd to the main worktree first, or the shell ends up in a deleted directory.WORKTREE READY
==============
Action: CREATE | CLEANUP
Branch: <branch>
Path: <project>.worktrees/<slug>
Status: DONE | BLOCKED
Next:
- cd into the worktree path and open the editor there, or
- pull main yourself after a confirmed cleanup
For cleanup, only report DONE when the PR is confirmed MERGED (or --force was used deliberately); otherwise status is BLOCKED with the single reason the script reported.
tools
Idiomatic shell development for POSIX sh, Bash, Zsh, Fish, hooks, CI shell steps, and scriptable CLI glue. Use when writing or changing `.sh`, `.bash`, `.zsh`, `.fish`, `.bats`, shell functions, shell pipelines, or command-runner recipes. Emphasizes portability, quoting, safe filesystem/process handling, non-TUI CLI tools, ShellCheck, shfmt, Bats, and ShellSpec. NOT for Python, TypeScript, Go, web code, or infrastructure operations.
tools
Use when planning, executing, checkpointing, finishing, or inspecting lightweight spec-driven work. Runs one task at a time using `.spec/` markdown files and the bundled `specctl` helper. NOT for broad product discovery beyond a short requirement interview.
testing
Author, inspect, troubleshoot, and review infrastructure across IaC, Kubernetes, cloud resources, containers, CI/CD, and Linux hosts. Use when changing Terraform/OpenTofu, Kubernetes, Helm, Kustomize, Dockerfiles, GitHub Actions, AWS, GCP, Cloud Run, BigQuery, IAM, logs, instances, or service health. NOT for deploy/apply/rollback workflows (see deploying-infra). NOT for shell scripts or generic command pipelines (see writing-shell).
development
Configure safe git workflow hygiene: pre-commit/pre-push hooks, Gitleaks secret scanning, .gitignore rules, local git config, and guardrails. Use when setting up git hooks, gitleaks/git leaks, staged pre-commit checks, pre-push validation, core.hooksPath, .gitignore, or git config best practices. NOT for creating commits (use committing-code), cleaning branches/worktrees (use cleanup-git), or creating worktrees (use using-git-worktrees).