From empire-git
Closes a single git worktree: checks for uncommitted changes, optionally pushes the branch, then removes the worktree and lets the user decide the branch's fate.
How this skill is triggered — by the user, by Claude, or both
Slash command
/empire-git:worktree-close [branch | path] [--push] [--discard] [--force][branch | path] [--push] [--discard] [--force]sonnetThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Finish work in a worktree: check for unsaved work, optionally push, remove the worktree, and let the user decide what happens to the branch.
Finish work in a worktree: check for unsaved work, optionally push, remove the worktree, and let the user decide what happens to the branch.
User input: $ARGUMENTS
Flag semantics (do not conflate):
| Flag | Meaning |
|---|---|
--push | Push the branch to origin before removing the worktree. |
--discard | Skip the dirty-check prompt and proceed even with uncommitted changes. |
--force | Skip the cleanup-option prompt; default to "remove worktree + delete branch". |
--discard and --force are independent. The user can pass either, both, or neither. Never treat one as implying the other.
Priority order:
$ARGUMENTS contains a branch name or worktree path, use that.git worktree list and ask the user to pick one.Parse git worktree list --porcelain to find the worktree path and branch. Identify the main working tree (the first entry) — it cannot be closed.
git -C "<worktree-path>" status --porcelain
If clean (empty output): proceed to Step 3.
If dirty (uncommitted changes):
Show the user what's pending:
git -C "<worktree-path>" status --short
Then present options:
/commit in the worktree, then re-run /empire-git:worktree-closeIf --discard was in $ARGUMENTS, skip this prompt and proceed with force removal of uncommitted work.
If --push was in $ARGUMENTS, or the user mentioned pushing:
git -C "<worktree-path>" push -u origin "<branch>"
If push fails, report the error and stop. If no --push flag, skip this step.
If there are unpushed commits and the user did NOT request --push, mention it:
This branch has X unpushed commit(s) that are not backed up to the remote. Add
--pushto push before closing, or continue to close without pushing.
Ask the user what they'd like to do. Present these choices:
git branch -d (safe delete — refuses if unmerged).Pick a sensible default based on context:
If --force was specified, skip the cleanup-option prompt and use option 2 (but still use safe delete with git branch -d).
Run the chosen option (1 or 2) as a single Bash call. Claude Code's Bash tool resolves the shell's cwd once at the start of each invocation and does not carry shell variables between invocations. If the session is inside the worktree, removing it makes the cwd vanish — so any separate later Bash call (prune, registry update, even git -C) fails before it starts, and MAIN_REPO would be empty besides. Keeping remove, branch delete, prune, and deregister in one call sidesteps both problems: cwd is read once before anything is deleted, and every git command is anchored to the main working tree with git -C "$MAIN_REPO". awk uses substr($0, 10) rather than $2 so worktree paths containing spaces are not truncated.
MAIN_REPO=$(git worktree list --porcelain | awk '/^worktree / { print substr($0, 10); exit }')
git -C "$MAIN_REPO" worktree remove "<worktree-path>"
git -C "$MAIN_REPO" worktree prune
bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-registry.sh" remove "<worktree-path>"
If the worktree is dirty and the user confirmed discard (or passed --discard), swap the remove for git -C "$MAIN_REPO" worktree remove --force "<worktree-path>".
git branch -d refuses to delete a branch still checked out in a worktree, so the worktree is removed first. -d is a safe delete; if it fails, the branch has unmerged commits — keep it and surface the message below rather than force-deleting. The later lines still run, so the worktree is pruned and deregistered even when the branch is kept.
MAIN_REPO=$(git worktree list --porcelain | awk '/^worktree / { print substr($0, 10); exit }')
git -C "$MAIN_REPO" worktree remove "<worktree-path>"
git -C "$MAIN_REPO" branch -d "<branch>"
git -C "$MAIN_REPO" worktree prune
bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-registry.sh" remove "<worktree-path>"
If git branch -d fails (branch not fully merged), tell the user:
Branch '' has unmerged commits. Keeping the branch. To force-delete:
git branch -D <branch>
Do nothing. Confirm to the user that the worktree is still active.
For options 1 and 2 the prune and registry deregister already ran inside the Step 5 call (the registry remove is idempotent — a no-op if the entry is absent). If either printed a warning, mention it but continue; the worktree removal already succeeded. Option 3 removed nothing, so there is nothing to confirm beyond the worktree staying active.
Print a summary:
Worktree closed.
Path: <worktree-path> (removed)
Branch: <branch> (deleted | kept | pushed)
The main working tree is not a worktree. It's the user's primary repo checkout — removing it would be catastrophic. If someone accidentally targets it, explain the difference.
Uncommitted work is sacred. Silently discarding changes is one of the worst things a tool can do. The user should always see what's at risk and explicitly choose to discard. The --discard flag exists for when they've already made that choice. --force only skips the cleanup-option prompt — it does NOT authorize discarding uncommitted work.
Use git branch -d (safe delete), not -D. If -d refuses, it means the branch has unmerged commits — that's valuable information to surface, not override. Tell the user the command to force-delete if they really want to.
Use git worktree remove, not rm -rf. Git tracks worktree metadata internally; removing the directory without telling git leaves stale references that cause confusing errors later. If anything goes wrong, git worktree prune cleans up the metadata.
Creates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.
npx claudepluginhub marcoskichel/empire --plugin empire-git