Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions scripts/remove-worktree.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Usage:
# remove-worktree.sh <path-or-branch> [options]
#
# <path-or-branch> Worktree path (e.g. .claude/rig-worktrees/feat-521-foo) or
# <path-or-branch> Worktree path (e.g. .claude/worktrees/feat-521-foo) or
# the branch checked out in it (e.g. alice/feat-521-foo).
#
# Options:
Expand Down Expand Up @@ -97,4 +97,10 @@ fi
git -C "$MAIN" worktree prune >&2

echo "removed $WT_PATH"
echo "remove-worktree: removed $WT_PATH${KEEP_BRANCH:+ (kept branch)}" >&2
# KEEP_BRANCH is "0" when unset — non-empty, so ${KEEP_BRANCH:+…} fires either
# way. Compare it, or the script claims it kept a branch it just force-deleted.
if [ "$KEEP_BRANCH" = "1" ]; then
echo "remove-worktree: removed $WT_PATH (kept branch)" >&2
else
echo "remove-worktree: removed $WT_PATH${BRANCH:+ (deleted branch $BRANCH)}" >&2
fi
33 changes: 21 additions & 12 deletions scripts/setup-worktree.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# e.g. from vcs.baseRef in .rig/config.json).
# Pass origin/<integration-branch> for stacked children.
# --path <path> Worktree path. Default:
# .claude/rig-worktrees/<basename-of-branch>.
# .claude/worktrees/<basename-of-branch>.
# --reuse If the worktree (or branch) already exists, reuse it:
# fetch + hard-reset to <base> instead of failing.
# Without this, an existing path/branch is an error.
Expand Down Expand Up @@ -80,9 +80,12 @@ done
MAIN=$(git worktree list --porcelain | awk '/^worktree / && !seen { print $2; seen=1 }')
[ -n "$MAIN" ] || die "could not resolve main worktree root"

# Default worktree path: .claude/rig-worktrees/<last segment of branch>.
# Default worktree path: .claude/worktrees/<last segment of branch>. This is the
# directory the Claude Code harness manages, so a worktree created here can be
# adopted natively via EnterWorktree/ExitWorktree (a sibling .claude/rig-worktrees/
# path could not). Override with --path.
if [ -z "$WT_PATH" ]; then
WT_PATH="$MAIN/.claude/rig-worktrees/${BRANCH##*/}"
WT_PATH="$MAIN/.claude/worktrees/${BRANCH##*/}"
fi
# Normalize to absolute.
case "$WT_PATH" in
Expand Down Expand Up @@ -125,10 +128,12 @@ if [ -d "$WT_PATH" ]; then
else
# Create the worktree. -B so an already-existing local branch is reset to
# base rather than erroring; this matches a stacked integration-branch flow.
# git worktree add prints "HEAD is now at …" to stdout; route it to stderr so
# stdout carries only the final path line (the caller's `| tail -1` contract).
if [ "$REUSE" = "1" ]; then
git -C "$MAIN" worktree add -B "$BRANCH" "$WT_PATH" "$BASE"
git -C "$MAIN" worktree add -B "$BRANCH" "$WT_PATH" "$BASE" >&2
else
git -C "$MAIN" worktree add -b "$BRANCH" "$WT_PATH" "$BASE"
git -C "$MAIN" worktree add -b "$BRANCH" "$WT_PATH" "$BASE" >&2
fi
fi

Expand All @@ -137,13 +142,17 @@ fi
# missing secrets look like flaky/timeout test failures, not "config not found".
# Symlinks (not copies) so edits in MAIN propagate; ln -sfn is idempotent.
echo "setup-worktree: symlinking env files..." >&2
(
cd "$MAIN"
git ls-files --others --ignored --exclude-standard
) | grep -v '/node_modules/' | grep -v '^node_modules/' \
| grep -v '\.example$' \
| grep -E '(^|/)\.env(\.[^/]+)?$' \
| while read -r f; do
# `|| true` guards the whole filter chain: any grep stage that selects no lines
# exits 1, and under `set -o pipefail` that would abort the script — but "this
# repo has no .env files to link" is a normal outcome, not a failure.
{
(
cd "$MAIN"
git ls-files --others --ignored --exclude-standard
) | grep -v '/node_modules/' | grep -v '^node_modules/' \
| grep -v '\.example$' \
| grep -E '(^|/)\.env(\.[^/]+)?$' || true
} | while read -r f; do
mkdir -p "$WT_PATH/$(dirname "$f")"
ln -sfn "$MAIN/$f" "$WT_PATH/$f"
done
Expand Down
8 changes: 5 additions & 3 deletions skills/rig-worktree/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ allowed-tools: [Bash, Read]

# Worktree — isolated dev checkout lifecycle

Create / list / remove isolated git worktrees under `.claude/rig-worktrees/`.
Create / list / remove isolated git worktrees under `.claude/worktrees/`.
Creation produces a worktree that's actually ready to run: fetched from
origin, branched from the right base, env files symlinked, dependencies
installed. This is a shared bootstrap you can call directly (spikes,
Expand Down Expand Up @@ -59,8 +59,10 @@ only required argument.
- `--base <ref>` — base to branch from. Default `vcs.baseRef`. For a
stacked/integration child, pass `origin/<integration-branch>`.
- `--path <path>` — worktree location. Default
`.claude/rig-worktrees/<last segment of branch>` (so `alice/feat-521-foo`
→ `.claude/rig-worktrees/feat-521-foo`).
`.claude/worktrees/<last segment of branch>` (so `alice/feat-521-foo`
→ `.claude/worktrees/feat-521-foo`). This is the directory the Claude Code
harness manages, so a worktree created here can be adopted natively via
`EnterWorktree`/`ExitWorktree`.
- `--reuse` — if the worktree/branch already exists, fetch and
hard-reset it to `<base>` instead of failing. Use this for a
"reuse a child worktree" path.
Expand Down
Loading