$npx -y skills add alexei-led/cc-thingz --skill cleanup-gitClean local git branches and worktrees after work has merged. Dry-run first. Destructive commands require user approval.
| 1 | # Cleanup Git |
| 2 | |
| 3 | Clean local git branches and worktrees after work has merged. Dry-run first. Destructive commands require user approval. |
| 4 | |
| 5 | Prefer a repo-local `scripts/cleanup-git.sh` when the target repo ships one. If it does not, use the bundled skill script from this skill's `scripts/` directory. Do not improvise destructive cleanup commands outside the script workflow. |
| 6 | |
| 7 | ## Command |
| 8 | |
| 9 | Run from anywhere inside a repository: |
| 10 | |
| 11 | ```bash |
| 12 | scripts/cleanup-git.sh |
| 13 | scripts/cleanup-git.sh --apply |
| 14 | scripts/cleanup-git.sh --apply --force |
| 15 | scripts/cleanup-git.sh --base <ref> |
| 16 | ``` |
| 17 | |
| 18 | ## Branch Detection |
| 19 | |
| 20 | The script fetches/prunes remotes, then chooses the comparison branch: |
| 21 | |
| 22 | 1. Remote default branch from `refs/remotes/<remote>/HEAD`. |
| 23 | 2. Local `main`, `master`, `trunk`, `develop`, or `dev`. |
| 24 | 3. Remote `<remote>/{main,master,trunk,develop,dev}`. |
| 25 | |
| 26 | Use `--base <ref>` only for unusual repositories. |
| 27 | |
| 28 | ## What It Removes |
| 29 | |
| 30 | - Worktrees whose branch has a GitHub PR in `MERGED` state, is merged into the detected base branch, or whose upstream is gone. |
| 31 | - Local branches with the same criteria. |
| 32 | |
| 33 | When `gh` is available, PR `MERGED` state is the source of truth for squash/rebase merges. Do not miss those just because `git merge-base --is-ancestor` fails after history rewrite. If no PR is found, or `gh` is unavailable, fall back to the git-based checks. |
| 34 | |
| 35 | ## Guards |
| 36 | |
| 37 | Hard guards: |
| 38 | |
| 39 | - Skip the current worktree. |
| 40 | - Skip the current branch. |
| 41 | - Skip the detected base branch and common long-lived branches: `main`, `master`, `trunk`, `develop`, `dev`. |
| 42 | - Keep worktrees with uncommitted changes. |
| 43 | |
| 44 | Soft guard: |
| 45 | |
| 46 | - Keep items with commits ahead of the base branch. `--force` overrides only this guard. |
| 47 | - For merged PRs, treat only commits added after the PR head as "ahead". A squash/rebase-merged branch with no new local commits is still removable. |
| 48 | |
| 49 | ## Workflow |
| 50 | |
| 51 | 1. Run `scripts/cleanup-git.sh` and show the preview. |
| 52 | 2. Read reasons literally: `remove ... (PR merged)`, `remove ... (upstream gone)`, `KEEP ... (dirty)`, `KEEP ... (PR merged, N ahead — use --force)`. |
| 53 | 3. Surface every `KEEP` line as a human decision. |
| 54 | 4. Ask before running `scripts/cleanup-git.sh --apply`. |
| 55 | 5. Use `--force` only when the user confirms ahead commits are throwaway. |
| 56 | |
| 57 | ## Output |
| 58 | |
| 59 | ```text |
| 60 | GIT CLEANUP |
| 61 | =========== |
| 62 | Status: PREVIEW | APPLIED | BLOCKED |
| 63 | Base: <ref> |
| 64 | |
| 65 | Remove: |
| 66 | - <branch/worktree> — <reason> |
| 67 | |
| 68 | Keep: |
| 69 | - <branch/worktree> — <reason and user decision needed> |
| 70 | |
| 71 | Verification: |
| 72 | - <command> — pass/fail/not run |
| 73 | ``` |
| 74 | |
| 75 | ## Conditional References |
| 76 | |
| 77 | - [gh-cli.md](references/gh-cli.md) — read when `gh` is available and PR-state detection is needed: squash/rebase merge detection, rate-limit batching, offline fallback. |
| 78 | |
| 79 | ## Failure Handling |
| 80 | |
| 81 | - Not a git repo: say so and stop. |
| 82 | - Base branch not found: ask for `--base <ref>`. |
| 83 | - Fetch fails during preview: report that refs may be stale. |
| 84 | - Fetch fails during apply: stop; do not delete with stale refs. |
| 85 | - Dirty worktree: keep it and ask the user what to do. |
| 86 | - Ahead commits: keep unless the user explicitly approves `--force`. |