- name
- git-cleanup
- description
- Repository hygiene — prune merged/stale branches, detect orphans, repo health checks. Use when cleaning up branches, checking repo health, or scanning projects.
- metadata
- {"author":"GhostWorks"}
# Git Repository Cleanup
Repository hygiene: prune branches, detect stale work, and check repo health.
Parse the user's input to determine the action:
- `$git-cleanup` or `$git-cleanup branches` — find and prune merged/stale branches
- `$git-cleanup stale [days]` — branches with no commits in N days (default 30)
- `$git-cleanup health` — large files, dangling refs, worktrees, repo size
- `$git-cleanup all` — scan all git repos under ~/Projects/
## Prerequisites
1. Verify we're in a git repository (`git rev-parse --is-inside-work-tree`) — except for `all` action which scans directories
2. If not in a git repo (and not using `all`), tell the user and stop
## Protected Branches
The following branches are NEVER suggested for deletion: `main`, `master`, `develop`
## Action: branches (default)
1. Fetch latest remote state: `git fetch --prune`
2. Identify the default branch (`git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null` or fall back to `main`/`master`)
3. Find merged branches:
- `git branch --merged <default>` — local branches already merged into default
- Exclude protected branches and current branch
4. Find branches with deleted remotes:
- `git branch -vv` — look for `[origin/...: gone]` entries
5. Present findings as a **dry-run preview**:
- List branches that can be safely deleted (merged)
- List branches whose remote is gone
- Show last commit date and message for each
6. Ask the user which branches to delete (or "all listed")
7. On confirmation, delete with `git branch -d <branch>` (safe delete)
8. If a branch fails `-d` (unmerged), warn the user and offer `-D` with explicit explanation that commits may be lost — only proceed with user confirmation
## Action: stale [days]
1. Default to 30 days if no argument provided
2. For each local branch (excluding protected branches):
- Get last commit date: `git log -1 --format='%ci' <branch>`
- Calculate age in days
3. List branches older than the threshold, sorted by age (oldest first)
4. Show for each: branch name, last commit date, last commit message, age in days
5. Present as dry-run preview — ask before deleting
6. On confirmation, use `git branch -d` first; offer `-D` only with warning if unmerged
## Action: health
Run a comprehensive repository health check:
1. **Repository size**:
- `.git` directory size: `du -sh .git`
- Working tree size: `du -sh . --exclude=.git` (or equivalent)
- Object count: `git count-objects -vH`
2. **Large files** (top 10 by size in history):
- `git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print $3, $4}' | sort -rn | head -10`
- Flag files over 10MB
3. **Dangling objects**:
- `git fsck --no-reflogs 2>&1` — look for dangling commits, blobs, trees
- Report count and suggest `git gc` if significant
4. **Worktrees**:
- `git worktree list` — show active worktrees
5. **Remote status**:
- `git remote -v` — list remotes
- Check if local is ahead/behind remote
6. **Stale tracking branches**:
- `git remote prune origin --dry-run` — branches that would be pruned
7. Present findings with recommendations
8. If cleanup is recommended (gc, prune), show the commands but **always ask before running them**
## Action: all
1. Find all git repositories under `~/Projects/`:
- `find ~/Projects -maxdepth 3 -name .git -type d`
2. For each repository found:
a. Show repo name and path
b. Run the **branches** check (merged + gone remotes)
c. Show summary: N merged branches, M gone-remote branches
3. **Per-repo confirmation** — ask before deleting branches in each repo
4. Show overall summary at the end
## Safety Rules
1. **Never delete without confirmation** — always preview first
2. **Never delete protected branches** (main, master, develop)
3. **Never `git push origin --delete` on protected branches**
4. **Never run `git gc` without asking**
5. **Always preview first** — every action starts as a dry run
6. **Per-repo confirmation for `all`** — don't batch-delete across repos
7. Use `git branch -d` (safe delete) first; only offer `-D` with explicit warning
在 GitHub 查看