| name | worktree-workflow |
| description | This skill should be used when "creating a worktree", "worktree naming", "ephemeral branch", "merge from worktree", "worktree cleanup", or navigating between worktrees. Covers naming conventions, ephemeral branch patterns, the CWD trap, and worktree setup. Do not use for general git workflow. |
Worktree Workflow
Git worktree patterns for parallel development work. Enables
working on multiple features/tickets simultaneously without
branch switching.
Core Convention
All worktrees live in _worktrees/ subfolder:
{repo}/ # Main checkout (on main)
{repo}/_worktrees/ # Worktrees folder
{repo}/_worktrees/{worktree-name}/ # Individual worktree
Naming Conventions
Forge Slice Worktrees
| Element | Pattern | Example |
|---|
| Folder | {slice-slug} | auth-refactor |
| Branch | slice/{slug}-{phase}-{suffix} | slice/auth-refactor-design-a1b2 |
Forge Effort Worktrees
| Element | Pattern | Example |
|---|
| Folder | {effort-slug} | cloud-migration |
| Branch | effort/{slug}-{suffix} | effort/cloud-migration-a1b2 |
Implementation Ticket Worktrees
| Element | Pattern | Example |
|---|
| Folder | {feature-slug}-{ticket-num} | auth-refactor-42 |
| Branch | {feature-slug}/{ticket-num}-{desc} | auth-refactor/42-jwt-validation |
Ephemeral Branch Pattern
Branches are single-use: create → push → merge → delete
- Each set of changes gets a unique branch
- After merge, create a fresh branch for next changes
- No branch resets needed — each PR starts fresh from main
- Multiple contributors can work in parallel
Example lifecycle:
slice/auth-refactor-requirements-a1b2 # Created, merged, deleted
slice/auth-refactor-design-c3d4 # Created, merged, deleted
slice/auth-refactor-impl-e5f6 # Created, merged, deleted
Why? Eliminates the painful reset cycle:
merge → git reset --hard origin/main → git push --force
Creating a Worktree
Always specify the starting branch (typically origin/main)
when creating with -b — omitting it starts the branch from
current HEAD, which may be a feature branch, pulling
unrelated commits into your PR.
Manual Creation
mkdir -p _worktrees
git worktree add _worktrees/auth-refactor \
-b slice/auth-refactor-design-a1b2 origin/main
cd _worktrees/auth-refactor
Common Mistake: Omitting Base Branch
git worktree add _worktrees/my-feature -b feature/my-feature
git worktree add _worktrees/my-feature \
-b feature/my-feature origin/main
Working in a Worktree
cd {repo}/_worktrees/{worktree-name}
git status
git add .
git commit -m "feat(scope): Description"
git push -u origin {branch-name}
Merging PRs
IMPORTANT: Always merge from main repository, not from
worktrees.
The Problem
cd _worktrees/my-feature
gh pr merge 123 --rebase --delete-branch
Why: The --rebase merge needs to check out main, which
is already checked out in the main repository directory.
The Solution
cd _worktrees/my-feature
git push
cd ../..
gh pr merge 123 --rebase --delete-branch
Alternative: Web UI
Merge via GitHub's web interface (no worktree limitation).
Use "Rebase and merge" to maintain linear history.
Removing a Worktree
git worktree remove _worktrees/{worktree-name}
git branch -d {branch-name}
CRITICAL: CWD Trap That Kills Your Session
If the shell's CWD is inside a worktree directory when that
directory is deleted, the shell breaks permanently for the
session. Even echo hello will fail.
How it happens:
- You work in a worktree (CWD persisted to worktree dir)
- You chain:
cd /repo && git worktree remove _worktrees/X
- The remove succeeds but a chained branch delete fails
- Shell does not persist the cd from a failed command
- Next command tries to start in the deleted directory
Prevention:
- cd to repo root in a separate shell call before removing
- Never chain cd and remove in one command
cd /repo && git worktree remove _worktrees/X
cd /repo
git worktree remove _worktrees/X
Navigation Best Practices
Problem: Relative paths (_worktrees/...) only work from
repo root. If you're already inside a worktree, they fail.
Use Absolute Paths
WORKTREE_PATH=$(git worktree list | \
grep "my-feature" | awk '{print $1}')
CURRENT=$(pwd)
if [ "$CURRENT" = "$WORKTREE_PATH" ]; then
echo "Already in worktree"
else
cd "$WORKTREE_PATH"
fi
Navigate to Repo Root First
cd "$(git rev-parse --show-toplevel)"
cd _worktrees/my-feature
Listing Worktrees
git worktree list
Best Practices
-
One Work Item Per Worktree
- Don't mix multiple tickets/features
- Makes PRs cleaner and easier to review
-
Clean Up After Merge
- Remove worktrees after PR merge
- Prevents accumulation of stale directories
-
Keep Main Clean
- Don't make changes in main checkout
- Use worktrees for all feature/ticket work
-
Consistent Naming
- Follow naming conventions strictly
- Makes automation and scripting easier
-
Merge from Main Checkout
- Always run
gh pr merge from main repository
Troubleshooting
Worktree Already Exists
git worktree list | grep {name}
git worktree prune
git worktree add _worktrees/{name} -b {branch} origin/main
Branch Already Exists
git worktree add _worktrees/{name} {existing-branch}
git branch -D {branch}
git worktree add _worktrees/{name} -b {branch} origin/main
"No such file or directory" When Navigating
Symptom: cd _worktrees/my-feature fails even though
git worktree list shows it exists.
Cause: Using relative path from inside another worktree.
Solution: Use absolute paths from git worktree list.
Summary
| Aspect | Pattern |
|---|
| Location | {repo}/_worktrees/ |
| Naming | {slug} or {slug}-{ticket-num} |
| Branch | Ephemeral, single-use |
| Creation | ALWAYS specify origin/main as base |
| Merging | ALWAYS from main repo, not worktree |
| Navigation | Use absolute paths, never relative |
Key principles:
- Ephemeral branches (single-use, no resets)
- Absolute paths (never rely on relative paths)
- Merge from main (avoid worktree limitations)
- One work item per worktree (clear separation)