Reconcile
Consolidate worktrees into the main worktree and clean up stale branches for a project.
Arguments
Accepts an optional project name as an argument:
/reconcile — reconcile the current working directory's project
/reconcile py-lintro — reconcile the project at ~/Code/py-lintro
Workflow
Phase 1 — Discovery
Identify the project root:
- If a project name is given, look for
~/Code/<project-name>
- Otherwise, use the current git repository root
- Confirm it's a git repository — if not, stop
Find all worktrees:
git worktree list
Find sibling directories that may be related:
- List directories matching
<project-name>-* in the same parent directory
- For each, check if it's:
- A worktree (
.git is a file pointing to the main repo)
- A separate clone (
.git is a directory with same remote)
- Unrelated (different remote or not a git repo) — ignore these
Collect all branches:
git branch -vv --no-color
Phase 2 — Analysis
For each branch (excluding main/master), determine its status:
Check remote tracking:
- If tracking branch shows
gone → remote branch was deleted (PR likely merged or
closed)
- If tracking branch exists → check PR status
Check GitHub PR status (if gh is available):
gh pr list --state all --json number,title,headRefName,state
- Map each branch to its PR (if any)
- Categorize:
merged, open, closed (without merge), or no PR
Check for uncommitted changes in each worktree:
git -C <worktree-path> status --short
Check for stashes:
git stash list
Check if main worktree is on main — flag if it's on a feature branch
Phase 3 — Report
Present a summary to the user, grouped by action:
Project: turbo-themes
Main worktree: ~/Code/turbo-themes (on refactor/265 — should be main)
Worktrees to remove:
✅ turbo-themes-267-... → fix/267-text-contrast (PR #350 merged, clean)
✅ turbo-themes-build-.. → fix/build-ci-site (PR #359 merged, clean)
⚠️ turbo-themes-ci-... → fix/ci-missing-rose (PR #356 merged, 3 uncommitted files)
Branches to delete (PRs merged):
fix/267-text-contrast-state-buttons-light-themes
fix/build-ci-site-missing-core-dep
fix/ci-missing-rose-pine-synced
Branches to keep:
📌 feat/landing-page-redesign — no PR, unmerged work
Separate clones found:
🔶 ~/Code/turbo-themes-test — separate clone, not a worktree
Stashes: 5 (all on merged branches)
Phase 4 — Confirm
Ask the user to confirm the plan (use a structured question tool if available):
- Which branches to keep vs delete
- Whether to remove separate clones
- Whether to clear stale stashes
- Confirm that uncommitted changes will be stashed
Do NOT proceed without explicit confirmation.
Phase 5 — Execute
After confirmation, perform the cleanup in this order:
Remove worktree directories:
- Try
git worktree remove <path> first
- Before any fallback delete, resolve
<path> to a canonical path and verify all of
the following:
- Path is non-empty and exists
- Path is NOT
/ and NOT the home directory
- Path is under an allowed prefix (repo sibling worktree/clone root)
- Path is not a symlink escaping the allowed prefix
- Only with explicit user confirmation, if removal still fails (orphaned directory),
run
rm -rf <path> then git worktree prune
Stash uncommitted changes (if any, on branches being kept):
git -C <worktree-path> stash push -m "reconcile: WIP on <branch-name>"
Switch main worktree to the default branch:
DEFAULT_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's#^origin/##')
git checkout "$DEFAULT_BRANCH"
git pull
Delete merged branches:
git branch -d <branch1> <branch2> ...
Clear stale stashes (only if user confirmed):
- Drop stashes that reference deleted branches
Remove separate clones (only if user confirmed):
rm -rf <clone-path>
- Apply the same canonical path-safety checks before deletion (non-empty, exists, not
/ or home, within allowed prefix, no symlink escape)
Phase 6 — Verify
Print the final state:
=== worktrees ===
~/Code/turbo-themes abc1234 [main]
=== branches ===
feat/landing-page-redesign def5678 unmerged work
* main abc1234 [origin/main] latest commit message
=== stashes ===
(none)
Important
- NEVER delete branches or worktrees without asking the user first
- ALWAYS stash uncommitted changes before cleanup
- NEVER force-push or modify remote state
- NEVER delete
main or master branches
- Always present the full picture before taking action
- If a directory can't be identified as a worktree or clone, flag it and ask — don't
assume
- If
gh is not available, fall back to checking remote tracking status only
- Branches with open PRs should default to "keep" in the recommendation
- Branches with no PR and no remote should be flagged for user decision
1---2name: reconcile3description: Consolidate worktrees and clean up stale branches. Use when asked to reconcile, clean up worktrees, consolidate branches, or tidy up a project's git state.4---56# Reconcile78Consolidate worktrees into the main worktree and clean up stale branches for a project.910## Arguments1112Accepts an optional project name as an argument:1314- `/reconcile` — reconcile the current working directory's project15- `/reconcile py-lintro` — reconcile the project at `~/Code/py-lintro`1617## Workflow1819### Phase 1 — Discovery20211. **Identify the project root**:22 - If a project name is given, look for `~/Code/<project-name>`23 - Otherwise, use the current git repository root24 - Confirm it's a git repository — if not, stop25262. **Find all worktrees**:2728 ```bash29 git worktree list30 ```31323. **Find sibling directories** that may be related:33 - List directories matching `<project-name>-*` in the same parent directory34 - For each, check if it's:35 - A **worktree** (`.git` is a file pointing to the main repo)36 - A **separate clone** (`.git` is a directory with same remote)37 - **Unrelated** (different remote or not a git repo) — ignore these38394. **Collect all branches**:4041 ```bash42 git branch -vv --no-color43 ```4445### Phase 2 — Analysis4647For each branch (excluding `main`/`master`), determine its status:48491. **Check remote tracking**:50 - If tracking branch shows `gone` → remote branch was deleted (PR likely merged or51 closed)52 - If tracking branch exists → check PR status53542. **Check GitHub PR status** (if `gh` is available):5556 ```bash57 gh pr list --state all --json number,title,headRefName,state58 ```5960 - Map each branch to its PR (if any)61 - Categorize: `merged`, `open`, `closed` (without merge), or `no PR`62633. **Check for uncommitted changes** in each worktree:6465 ```bash66 git -C <worktree-path> status --short67 ```68694. **Check for stashes**:7071 ```bash72 git stash list73 ```74755. **Check if main worktree is on `main`** — flag if it's on a feature branch7677### Phase 3 — Report7879Present a summary to the user, grouped by action:8081```text82Project: turbo-themes83Main worktree: ~/Code/turbo-themes (on refactor/265 — should be main)8485Worktrees to remove:86 ✅ turbo-themes-267-... → fix/267-text-contrast (PR #350 merged, clean)87 ✅ turbo-themes-build-.. → fix/build-ci-site (PR #359 merged, clean)88 ⚠️ turbo-themes-ci-... → fix/ci-missing-rose (PR #356 merged, 3 uncommitted files)8990Branches to delete (PRs merged):91 fix/267-text-contrast-state-buttons-light-themes92 fix/build-ci-site-missing-core-dep93 fix/ci-missing-rose-pine-synced9495Branches to keep:96 📌 feat/landing-page-redesign — no PR, unmerged work9798Separate clones found:99 🔶 ~/Code/turbo-themes-test — separate clone, not a worktree100101Stashes: 5 (all on merged branches)102```103104### Phase 4 — Confirm105106Ask the user to confirm the plan (use a structured question tool if available):107108- Which branches to keep vs delete109- Whether to remove separate clones110- Whether to clear stale stashes111- Confirm that uncommitted changes will be stashed112113Do NOT proceed without explicit confirmation.114115### Phase 5 — Execute116117After confirmation, perform the cleanup in this order:1181191. **Remove worktree directories**:120 - Try `git worktree remove <path>` first121 - Before any fallback delete, resolve `<path>` to a canonical path and verify all of122 the following:123 - Path is non-empty and exists124 - Path is NOT `/` and NOT the home directory125 - Path is under an allowed prefix (repo sibling worktree/clone root)126 - Path is not a symlink escaping the allowed prefix127 - Only with explicit user confirmation, if removal still fails (orphaned directory),128 run `rm -rf <path>` then `git worktree prune`1291302. **Stash uncommitted changes** (if any, on branches being kept):131132 ```bash133 git -C <worktree-path> stash push -m "reconcile: WIP on <branch-name>"134 ```1351363. **Switch main worktree to the default branch**:137138 ```bash139 DEFAULT_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's#^origin/##')140 git checkout "$DEFAULT_BRANCH"141 git pull142 ```1431444. **Delete merged branches**:145146 ```bash147 git branch -d <branch1> <branch2> ...148 ```1491505. **Clear stale stashes** (only if user confirmed):151 - Drop stashes that reference deleted branches1521536. **Remove separate clones** (only if user confirmed):154155 ```bash156 rm -rf <clone-path>157 ```158159 - Apply the same canonical path-safety checks before deletion (non-empty, exists, not160 `/` or home, within allowed prefix, no symlink escape)161162### Phase 6 — Verify163164Print the final state:165166```text167=== worktrees ===168~/Code/turbo-themes abc1234 [main]169170=== branches ===171 feat/landing-page-redesign def5678 unmerged work172* main abc1234 [origin/main] latest commit message173174=== stashes ===175(none)176```177178## Important179180- NEVER delete branches or worktrees without asking the user first181- ALWAYS stash uncommitted changes before cleanup182- NEVER force-push or modify remote state183- NEVER delete `main` or `master` branches184- Always present the full picture before taking action185- If a directory can't be identified as a worktree or clone, flag it and ask — don't186 assume187- If `gh` is not available, fall back to checking remote tracking status only188- Branches with open PRs should default to "keep" in the recommendation189- Branches with no PR and no remote should be flagged for user decision