
Ce Worktree
- 1 installs
- 23.9k repo stars
- Updated August 5, 2026
- everyinc/compounding-engineering-plugin
Creates an isolated git worktree for parallel feature work or PR review, copying env files and handling mise/direnv trust with branch-aware safety rules.
About
Wraps git worktree creation with .env copying, gitignore setup, and branch-aware dev-tool trust so review branches do not auto-grant trust to untrusted configs. A developer uses it to start isolated feature or PR-review work without disturbing the main checkout.
- Copies .env files and trusts mise/direnv with baseline-checked safety
- Does not modify the main checkout; from-branch is fetched not checked out
Ce Worktree by the numbers
- 1 all-time installs (skills.sh)
- Ranked #524 of 733 Git & Pull Requests skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/everyinc/compounding-engineering-plugin --skill ce-worktreeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 23.9k |
| Last updated | August 5, 2026 |
| Repository | everyinc/compounding-engineering-plugin ↗ |
What it does
Creates an isolated git worktree for parallel feature work or PR review, copying env files and handling mise/direnv trust with branch-aware safety rules.
Files
Worktree Creation
Create a worktree under .worktrees/<branch> with branch-specific setup that git worktree add alone does not handle:
- Copies
.env,.env.local,.env.test, etc. from the main repo (skips.env.example) - Trusts
mise/direnvconfigs, with branch-aware safety rules so review branches do not auto-grant trust to untrusted.envrccontent - Adds
.worktreesto.gitignoreif not already ignored - Does not modify the main repo checkout —
from-branchis fetched, not checked out
Creating a worktree
Invoke the bundled script via the runtime Bash tool. On Claude Code, ${CLAUDE_SKILL_DIR} resolves to the skill's own directory across both marketplace-cached installs and claude --plugin-dir local development; the runtime Bash tool's CWD is the user's project, not the skill directory, so a bare bash scripts/worktree-manager.sh fails. On other targets (Codex, Gemini, Pi, etc.) ${CLAUDE_SKILL_DIR} is unset and the :-. fallback yields the bare relative path those harnesses expect.
bash "${CLAUDE_SKILL_DIR:-.}/scripts/worktree-manager.sh" create <branch-name> [from-branch]Defaults:
from-branchdefaults to origin's default branch (ormainif that cannot be resolved)- The new branch is created at
origin/<from-branch>(or the local ref if the remote is unavailable)
Examples:
bash "${CLAUDE_SKILL_DIR:-.}/scripts/worktree-manager.sh" create feat/login
bash "${CLAUDE_SKILL_DIR:-.}/scripts/worktree-manager.sh" create fix/email-validation developAfter creation, switch to the worktree with cd .worktrees/<branch-name>.
Other worktree operations
Use git directly — no wrapper is needed and none is provided:
git worktree list # list worktrees
git worktree remove .worktrees/<branch> # remove a worktree
cd .worktrees/<branch> # switch to a worktree
cd "$(git rev-parse --show-toplevel)" # return to main checkoutTo copy .env* files into an existing worktree created without them, run this from the main repo (not from inside the worktree, since branch names often contain slashes like feat/login):
cp .env* .worktrees/<branch>/Dev tool trust behavior
When mise or direnv configs are present, the script attempts to trust them so hooks and scripts do not block on interactive prompts. Trust is baseline-checked against a reference branch:
- Trusted base branches (
main,develop,dev,trunk,staging,release/*): the new worktree's configs are compared against that branch; unchanged configs are auto-trusted.direnv allowis permitted. - Other branches (feature branches, PR review branches): configs are compared against the default branch;
direnv allowis skipped regardless, because.envrccan source files that direnv does not validate.
Modified configs are never auto-trusted. The script prints the manual trust command to run after review.
When to create a worktree
Create a worktree when:
- Reviewing a PR while keeping the main checkout free for other work
- Running multiple features in parallel without branch-switching overhead
- Keeping the default branch free of in-progress state
Do not create a worktree for single-task work that can happen on a branch in the main checkout.
Integration
ce-work and ce-code-review offer this skill as an option. When the user selects "worktree" in those flows, invoke bash "${CLAUDE_SKILL_DIR:-.}/scripts/worktree-manager.sh" create <branch> with a meaningful branch name derived from the work description (e.g., feat/crowd-sniff, fix/email-validation). Avoid auto-generated names like worktree-jolly-beaming-raven that obscure the work.
Troubleshooting
"Worktree already exists": the path is already in use. Either switch to it (cd .worktrees/<branch>) or remove it (git worktree remove .worktrees/<branch>) before recreating.
"Cannot remove worktree: it is the current worktree": cd out of the worktree first, then git worktree remove.
Dev tool trust was skipped: the script prints the manual command. Review the config diff (git diff <base-ref> -- .envrc), then run the printed command from the worktree directory.
#!/bin/bash
#
# Create a new git worktree with environment files and dev-tool trust.
#
# The distinctive work this script does (vs. raw `git worktree add`):
# 1. Copies .env* files from the main repo (skipping .env.example)
# 2. Trusts mise/direnv configs with branch-aware safety rules,
# so hooks and scripts don't block on interactive trust prompts
# 3. Ensures .worktrees is gitignored (via `git check-ignore`)
#
# List / remove / switch operations are NOT provided here. Use git directly:
# git worktree list
# git worktree remove <path>
# cd <worktree-path> # switching is just `cd`
set -euo pipefail
# Resolve the main worktree's working tree, not the current worktree's toplevel.
# `git worktree list --porcelain` always emits the main worktree first. This
# handles normal repos, linked worktrees (where --show-toplevel would return
# the nested worktree), submodules (where --git-common-dir points under
# .git/modules), and --separate-git-dir setups (where --git-common-dir points
# to an external path). Parse with `sed` to preserve paths containing spaces
# (awk '{print $2}' would truncate them).
GIT_ROOT=$(git worktree list --porcelain | sed -n 's/^worktree //p' | head -n 1)
WORKTREE_DIR="$GIT_ROOT/.worktrees"
usage() {
cat <<'EOF'
Usage: worktree-manager.sh create <branch-name> [from-branch]
Creates .worktrees/<branch-name> with <branch-name> branched from
[from-branch] (default: origin's default branch, or main).
The main repo checkout is not modified; from-branch is fetched but
not checked out.
EOF
}
# Ensure .worktrees is ignored in the main repo. Runs `git check-ignore` from
# the main repo root so it sees the main repo's .gitignore (which is not
# inherited by linked worktrees). Falls back to a grep guard to avoid
# duplicate entries when check-ignore misses an uncommitted gitignore rule.
ensure_gitignore() {
if (cd "$GIT_ROOT" && git check-ignore -q .worktrees) 2>/dev/null; then
return
fi
if grep -Fxq ".worktrees" "$GIT_ROOT/.gitignore" 2>/dev/null; then
return
fi
echo ".worktrees" >> "$GIT_ROOT/.gitignore"
echo "Added .worktrees to .gitignore"
}
# Copy .env* files (except .env.example) from main repo to worktree.
# Backs up any pre-existing destination file.
copy_env_files() {
local worktree_path="$1"
local copied=0
shopt -s nullglob
for source in "$GIT_ROOT"/.env*; do
[[ -f "$source" ]] || continue
local name
name=$(basename "$source")
[[ "$name" == ".env.example" ]] && continue
local dest="$worktree_path/$name"
if [[ -f "$dest" ]]; then
cp "$dest" "${dest}.backup"
echo " Backed up existing $name to ${name}.backup"
fi
cp "$source" "$dest"
echo " Copied $name"
copied=$((copied + 1))
done
shopt -u nullglob
if [[ $copied -eq 0 ]]; then
echo " No .env files in main repo"
fi
}
get_default_branch() {
local head_ref
head_ref=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null || true)
if [[ -n "$head_ref" ]]; then
echo "${head_ref#refs/remotes/origin/}"
else
echo "main"
fi
}
# Auto-trust is only safe when the worktree is based on a long-lived branch
# the developer already controls. Review/PR branches fall back to the default
# branch baseline and require manual direnv approval.
is_trusted_base_branch() {
local branch="$1"
local default_branch="$2"
[[ "$branch" == "$default_branch" ]] && return 0
case "$branch" in
develop|dev|trunk|staging|release/*) return 0 ;;
*) return 1 ;;
esac
}
# Return 0 if worktree's copy of $file has the same blob hash as $base_ref's.
# Symlinks are rejected (can't verify content).
config_unchanged() {
local file="$1" base_ref="$2" worktree_path="$3"
[[ -L "$worktree_path/$file" ]] && return 1
local base_hash worktree_hash
base_hash=$(git rev-parse "$base_ref:$file" 2>/dev/null) || return 1
worktree_hash=$(git hash-object "$worktree_path/$file") || return 1
[[ "$base_hash" == "$worktree_hash" ]]
}
# Trust dev tool configs (mise, direnv) so hooks/scripts don't block on
# interactive trust prompts. Auto-trusts only when the config matches the
# trusted baseline branch.
trust_dev_tools() {
local worktree_path="$1" base_ref="$2" allow_direnv_auto="$3"
local trusted=0
local manual=()
if command -v mise &>/dev/null; then
for f in .mise.toml mise.toml .tool-versions; do
[[ -f "$worktree_path/$f" ]] || continue
if config_unchanged "$f" "$base_ref" "$worktree_path" \
&& (cd "$worktree_path" && mise trust "$f" --quiet); then
trusted=$((trusted + 1))
else
manual+=("mise trust $f")
fi
break
done
fi
if command -v direnv &>/dev/null && [[ -f "$worktree_path/.envrc" ]]; then
if [[ "$allow_direnv_auto" == "true" ]] \
&& config_unchanged ".envrc" "$base_ref" "$worktree_path" \
&& (cd "$worktree_path" && direnv allow); then
trusted=$((trusted + 1))
else
manual+=("direnv allow")
fi
fi
[[ $trusted -gt 0 ]] && echo " Trusted $trusted dev tool config(s)"
if [[ ${#manual[@]} -gt 0 ]]; then
echo " Manual review required for: ${manual[*]}"
echo " Review the diff, then run from $worktree_path"
fi
}
create_worktree() {
local branch_name="${1:-}"
local from_branch="${2:-}"
if [[ -z "$branch_name" ]]; then
echo "Error: branch name required" >&2
usage >&2
exit 1
fi
local default_branch
default_branch=$(get_default_branch)
from_branch="${from_branch:-$default_branch}"
local worktree_path="$WORKTREE_DIR/$branch_name"
if [[ -d "$worktree_path" ]]; then
echo "Error: worktree already exists at $worktree_path" >&2
echo "Use 'cd $worktree_path' to switch, or 'git worktree remove' first." >&2
exit 1
fi
echo "Creating worktree $branch_name from $from_branch"
mkdir -p "$WORKTREE_DIR"
ensure_gitignore
# Fetch from-branch without touching the main checkout.
if ! git fetch origin "$from_branch" --quiet; then
echo "Warning: could not fetch origin/$from_branch; using local ref" >&2
fi
# Prefer origin/<from> if available, else fall back to local ref.
local base_ref="origin/$from_branch"
if ! git rev-parse --verify "$base_ref" &>/dev/null; then
base_ref="$from_branch"
fi
git worktree add -b "$branch_name" "$worktree_path" "$base_ref"
echo "Environment files:"
copy_env_files "$worktree_path"
echo "Dev tool trust:"
local trust_branch="$default_branch"
local allow_direnv_auto="false"
if is_trusted_base_branch "$from_branch" "$default_branch"; then
trust_branch="$from_branch"
allow_direnv_auto="true"
fi
# Refresh the trust baseline before the hash-baseline check. Without this,
# a stale origin/<default_branch> can cause auto-trust against an outdated
# baseline when from_branch is untrusted (feature/review branches).
if [[ "$trust_branch" != "$from_branch" ]]; then
if ! git fetch origin "$trust_branch" --quiet; then
echo " Warning: could not fetch origin/$trust_branch; baseline may be stale" >&2
fi
fi
local trust_ref="origin/$trust_branch"
if git rev-parse --verify "$trust_ref" &>/dev/null; then
trust_dev_tools "$worktree_path" "$trust_ref" "$allow_direnv_auto"
else
echo " Skipped: $trust_ref not available locally"
fi
echo ""
echo "Worktree ready: $worktree_path"
echo "Switch with: cd $worktree_path"
}
main() {
local command="${1:-}"
shift || true
case "$command" in
create) create_worktree "$@" ;;
""|help|-h|--help) usage ;;
*)
echo "Error: unknown command '$command'" >&2
usage >&2
exit 1
;;
esac
}
main "$@"