with one click
worktree-end
// Inventory gitignored state, merge PR, and clean up a git worktree after task completion
// Inventory gitignored state, merge PR, and clean up a git worktree after task completion
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | worktree-end |
| description | Inventory gitignored state, merge PR, and clean up a git worktree after task completion |
Inventory and preserve gitignored state, merge the PR, then remove the worktree safely.
Pre-flight checks:
gh --version — abort with installation guidance if gh is not found.git rev-parse --git-common-dir must differ from git rev-parse --git-dir.
If they are equal, abort: the user must cd into the worktree first.PR resolution (idempotent):
Push the current branch if not already pushed (git push -u origin <branch>).
Then check for an existing open PR:
gh pr view --json state,url
state == OPEN → reuse the existing PR URL (do NOT create a duplicate).gh pr create --fill.
Display the PR URL.Ask the user:
First output the PR URL as a clickable markdown link in the main conversation:
PR #<N> is open: [<url>](<url>)
Then call AskUserQuestion: "PR # — merge, wait, or abort?"
If AskUserQuestion is unavailable (e.g. headless claude -p), default to wait.
Merge (only on explicit user choice):
gh pr merge --squash --delete-branch
If merge fails (protected branch policy, CI failure, conflict): surface the error and stop. Do not force-merge or bypass checks.
Gitignored state inventory (before removing the worktree): Run all three commands (NUL-delimited, handles spaces and non-ASCII paths):
git -C <worktree> ls-files --others --ignored --exclude-standard -z
git -C <worktree> ls-files --others --exclude-standard -z
git -C <worktree> status --porcelain=v1 -z
Also read WORKTREE_NOTES.md if it exists (created by /worktree-start).
Generate backup manifest — for each gitignored file: path, size, mtime, sha256. Do NOT include secret values in the manifest — metadata only.
Docker bind mount impact detection (both running and stopped containers):
docker ps -a --format json
Check whether any .Mounts.Source or env_file entry references the worktree path.
Normalize across path formats (WSL /mnt/<drive>/, Windows <DRIVE>:\, MSYS /drive/)
before comparing. Report stopped containers too: "Stopped containers included."
Present DRY RUN summary to the user:
<main_root>/.worktree-backup/<branch>/ (gitignored via .git/info/exclude)After user approval: copy preservation targets to the chosen destination. If Docker containers reference the worktree path, stop them and restart from the main path. Never delete gitignored state silently — always present the inventory first.
Cleanup (only after confirmed merge success and inventory — never before):
a. Resolve the main repo root from the worktree's .git file.
b. Write branch-delete marker so the enforce-worktree hook will permit
step f below. The marker lives in the SHARED .git directory so it is
readable from both the main worktree and any linked worktree.
<git-common-dir> via git -C <main> rev-parse --git-common-dir.
The marker path is <git-common-dir>/info/pending-branch-delete.<branch>
<absolute-worktree-path>
<absolute-worktree-path> must be the path being removed in step c, and
must resolve under WORKTREE_BASE_DIR (the hook re-validates this).git -C <main> worktree remove <path> (never --force — see rules).
d. git -C <main> worktree prune
e. If <WORKTREE_BASE_DIR>/<task-name>/ directory is now empty, delete it
(non-recursive to prevent accidents):rmdir "<WORKTREE_BASE_DIR>/<task-name>"Remove-Item "<WORKTREE_BASE_DIR>\<task-name>" (non-recursive)
f. git -C <main> branch -D <branch> — -D (force) is required because
squash-merge produces a new commit not recognised by -d's "fully merged"
check; the marker written in step b authorises this exact deletion.
g. Remove the marker at <git-common-dir>/info/pending-branch-delete
whether step f succeeded or failed (avoid leaving stale markers that
would let a later direct invocation slip past the hook).
h. git -C <main> fetch --prune origin
i. Verify cleanup: git -C <main> worktree list — confirm no stale entries.Why this dance: the enforce-worktree hook classifies git branch -d/-D
as a write op and blocks it from any worktree by default. The marker file is
the only authorised path; only this skill produces it. Direct ad-hoc
git branch -D from any worktree is intentionally rejected — this prevents
accidental loss of unmerged work and keeps cleanup auditable.
Final report: PR URL, merge state, backup manifest location, branches deleted, worktree path removed.
git worktree remove --force is prohibited unless the user gives explicit re-approval
after reviewing the rules/ops.md decision path.git branch -D only inside step 6f, gated by the
marker file written in step 6b. Direct ad-hoc git branch -d/-D outside this
skill is rejected by the enforce-worktree hook by design..worktree-backup/<branch>/ as the default backup destination; never silently pick a different path.gh --version must succeed before any gh command — surface installation guidance if not.