Skip to content
Back to skills

Full Branch Cleanup And Worktree Hygiene

ASecurity

Track all dirty/untracked workspace-hub changes, merge stale branches into main, clean remote/local branches, and remove stale worktrees while preserving tracked nested gitlinks.

  • 17 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 9, 2026
businesspythonrustbashgitsecurity

Works with

  • terminal

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add vamseeachanta/workspace-hub --skill full-branch-cleanup-and-worktree-hygiene --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Full Branch Cleanup And Worktree Hygiene?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Full Branch Cleanup And Worktree Hygiene
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/vamseeachanta-full-branch-cleanup-and-worktree-hygiene/badge)](https://www.skillsdirectory.com/skills/vamseeachanta-full-branch-cleanup-and-worktree-hygiene)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: full-branch-cleanup-and-worktree-hygiene
description: Track all dirty/untracked workspace-hub changes, merge stale branches into main, clean remote/local branches, and remove stale worktrees while preserving tracked nested gitlinks.
version: 1.0.0
author: Hermes Agent
tags: [git, branch-cleanup, worktree, workspace-hub, merge-hygiene]
---

# Full Branch Cleanup and Worktree Hygiene

Use when the user asks to:
- track all untracked files/changes
- merge work to origin/main
- merge all branches to `main`
- clean stale local/remote branches and worktrees

This is a high-side-effect workflow. It is appropriate only when the user explicitly authorizes broad branch cleanup.

## Core sequence

1. Start from a live inventory:
   ```bash
   git status --short --branch
   git branch -vv
   git branch -r
   git worktree list --porcelain
   git ls-remote --heads origin
   ```

2. Track dirty changes before branch deletion.
   - Commit root dirty/untracked files in a broad sync commit if the user asked to track all changes.
   - If a dirty path is itself a nested git repo/worktree/submodule, inspect it separately first.

3. Preserve nested gitlinks correctly.
   - Check whether a nested path is tracked as a gitlink:
     ```bash
     git ls-files -s <path>
     ```
   - Mode `160000` means the parent repo tracks a gitlink. Do not delete it as generic stale-worktree cleanup.
   - Commit inside the nested repo first:
     ```bash
     git -C <nested> add -A
     git -C <nested> commit -m "..."
     ```
   - Then stage/commit the parent gitlink update.

4. Merge current integration/feature branches to `main`.
   - Switch to `main` and fast-forward from origin first:
     ```bash
     git checkout main
     git pull --ff-only origin main
     ```
   - Identify branches that still contain unique commits:
     ```bash
     git rev-list --left-right --count main...<branch>
     ```
     The right-side count is `branch_only`; merge branches with `branch_only > 0`.
   - For remote-only branches, use `origin/<branch>` in the same check.

5. Resolve stale-branch conflicts conservatively.
   - For stale branches that conflict in planning indexes or duplicated artifacts, prefer current `main` for overlapping/conflicted files while accepting non-conflicting branch files:
     ```bash
     git checkout --ours -- <conflicted-file>
     git add <conflicted-file>
     git commit -m "Merge branch '<branch>' into main"
     ```
   - If a non-conflicting branch change triggers a security/content hook, drop just that file back to current `main` and record the reason in a handoff. Preserve unrelated review evidence/artifacts where safe.
   - Avoid bypassing hooks during cleanup unless explicitly approved and documented.

6. Push and verify remote state.
   - Push `main`.
   - GitHub may print `cannot lock ref ... is at <new> but expected <old>` even when the remote ref advanced. Always verify before retrying:
     ```bash
     git ls-remote --heads origin main
     git status --short --branch
     ```

7. Delete merged remote branches.
   - Only delete a remote branch if it is an ancestor of `main`:
     ```bash
     git merge-base --is-ancestor origin/<branch> main
     git push origin --delete <branch>
     ```
   - Then prune and verify:
     ```bash
     git fetch --all --prune
     git branch -r
     ```

8. Remove stale worktrees before deleting local branches.
   - Worktrees block branch deletion.
   - Remove stale worktrees with `git worktree remove -f <path>`.
   - Retain intentional tracked gitlinks/nested repos unless separately approved.
   - If there are dozens of worktrees, the removal loop may exceed tool/terminal timeouts. Treat timeout as partial progress: re-run `git worktree list --porcelain`, continue removing the remaining paths, then `git worktree prune`.
   - If `git worktree remove` reports a missing `.git` file for a stale path, run `git worktree prune` and re-check before attempting manual filesystem cleanup.
   - Run `git worktree prune` afterward.

9. Delete merged local branches.
   ```bash
   current=$(git branch --show-current)
   for b in $(git for-each-ref --format='%(refname:short)' refs/heads); do
     [ "$b" = "$current" ] && continue
     if git merge-base --is-ancestor "$b" main; then
       git branch -D "$b"
     fi
   done
   ```

10. Write a cleanup handoff and commit it.
    Include final branch/worktree state, retained gitlinks, merged branches, deleted remote branches, conflict-resolution choices, and next-session notes.

## Final verification checklist

Expected full-cleanup end-state:

```bash
git status --short --branch        # clean on main
git branch -a                      # only main + origin/main
git worktree list                  # main + intentional retained gitlinks only
git ls-remote --heads origin       # only refs/heads/main unless protected branches intentionally remain
```

Also verify no local branch has unique commits left:

```bash
python - <<'PY'
import subprocess
for b in subprocess.check_output(['git','for-each-ref','--format=%(refname:short)','refs/heads'], text=True).splitlines():
    if b == 'main':
        continue
    ahead = subprocess.check_output(['git','rev-list','--right-only','--count',f'main...{b}'], text=True).strip()
    print(b, ahead)
PY
```

## Pitfalls

- Do not remove a tracked gitlink just because `git worktree list` shows it as a detached worktree.
- Do not trust a failed-looking push if the error is `cannot lock ref`; verify with `git ls-remote`.
- Do not delete unmerged remote branches without proving ancestry into `main`.
- Do not let stale branch conflicts overwrite current planning indexes with older statuses.
- Do not normalize hook bypass during cleanup; prefer resolving or dropping the offending stale file.
- Auto-sync/background processes can create new dirty provider scorecards, planning markers, or handoffs immediately after a clean commit/push. Re-run `git status --short --branch` after every push/merge wave; if the user explicitly asked to track all changes, commit the new dirt too before declaring the checkout clean.
- Another terminal may approve an issue during cleanup, creating approval markers and plan/index updates while your handoff is being written. Before exit, revalidate live GitHub labels plus local `.planning/plan-approved/<issue>.md`, plan header, and `docs/plans/README.md`, then either commit the approval-state sync or document that it is already committed.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.