mcpField
G
git-branch-cleanup

git-branch-cleanup

github.com/gotalab開発41835 回インストール3 日前に更新
リポジトリ

git-branch-cleanup について

ローカル Git ブランチを安全に整理・削除するためのエージェントスキルです。マージ状態、リモート追跡、古さで分類し、削除前に安全確認と承認を行います。

主な機能

  1. 01安全性に応じたブランチ分類
  2. 02マージ済み、古い、リモート削除済みの識別
  3. 03現在のブランチと保護対象ブランチの保護
  4. 04未プッシュコミットと worktree の確認
  5. 05削除候補のプレビューと承認確認

活用シーン

  1. 01マージ済みローカルブランチの整理
  2. 02リモート削除済みや長期間更新のないブランチの確認
  3. 03削除前の未プッシュコミットと worktree の確認
  4. 04削除対象ブランチのプレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gotalab/skillport --skill git-branch-cleanup

インストール後、Claude Code で/git-branch-cleanupを入力して読み込まれたか確認します。

詳細

Git Branch Cleanup

ローカルの Git ブランチを安全に整理、クリーンアップします。マージ状況、古さ、リモート追跡の状態に基づいてブランチを分類し、安全に削除できるよう案内します。

Contents

  • クイックスタート
  • ワークフロー(ステップ 1~5)
  • コマンドリファレンス
  • ドライランモード
  • 安全チェックリスト

クイックスタート

  1. ブランチを分析する(ステップ 1)
  2. 安全レベルごとに分類する(ステップ 2)
  3. 結果を表示し、どのブランチを削除するかユーザーに尋ねる(ステップ 3)
  4. 安全ガードを確認する(ステップ 4)
  5. 確認後に削除を実行する(ステップ 5)

ワークフロー

ステップ 1:ブランチ分析

以下のコマンドで情報を収集します。

# Decide base branch (prefer auto-detect; fallback to main)
BASE_BRANCH="$(
  git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@'
)"
[ -n "$BASE_BRANCH" ] || BASE_BRANCH=main

# List all branches with last commit date
git for-each-ref --sort=-committerdate refs/heads/ \
  --format='%(refname:short)|%(committerdate:relative)|%(upstream:trackshort)|%(contents:subject)'

# Merged branches (against base)
git branch --merged "$BASE_BRANCH"

# Unmerged branches
git branch --no-merged "$BASE_BRANCH"

# Branches whose upstream is gone (remote deleted)
git branch -vv | grep -F ': gone]' || true

# List worktrees (branches with '+' prefix in git branch -v have worktrees)
git worktree list

# Branches with worktrees ('+' prefix indicates worktree association)
git branch -v | grep '^+' || true

# Branches ahead of upstream (have unpushed commits)
git for-each-ref refs/heads \
  --format='%(refname:short) %(upstream:trackshort)' \
  | grep '>' || true
ステップ 2:分類

ブランチを安全レベルごとに分類します。

カテゴリ説明安全性
マージ済み(安全)ベースブランチにすでにマージ済み安全に削除できます
リモートに存在しないリモートブランチが削除済み確認を推奨します
古いブランチ30 日以上コミットがない確認が必要です
ワークツリーありブランチがワークツリーでチェックアウトされている(git branch -v で + 接頭辞が表示される)先にワークツリーを削除します
上流より先行プッシュされていないコミットがある⚠️ 削除しないでください
未マージ作業が進行中注意して扱ってください

注:古いブランチを判定する基準として、30 日は妥当なデフォルト値です。必要に応じてチームのスプリントサイクルに合わせて調整してください(例:2 週間スプリントの場合は 14 日)。

ステップ 3:表示形式
## Branch Analysis Results

### Safe to Delete (Merged)
  - feature/login (3 weeks ago) - Add login feature
  - fix/typo (2 months ago) - Fix typo in readme

### Remote Deleted
  - feature/old-api (1 month ago) - Remote branch no longer exists

### ⚠️ Ahead of Upstream (DO NOT DELETE)
  - feature/wip (1 day ago) - Has 3 unpushed commits

### Stale Branches (30+ days)
  - experiment/cache (2 months ago) - Unmerged

### Active (Unmerged)
  - feature/new-dashboard (2 days ago) - Work in progress

---
Which categories would you like to delete?
1. Merged only (safest)
2. Merged + remote deleted
3. Select individually
ステップ 4:安全ガード

以下のブランチは削除しないでください。

  • main
  • master
  • trunk
  • develop
  • development
  • 現在チェックアウトされているブランチ

削除前に必ず確認します。

The following branches will be deleted:
  - feature/login
  - fix/typo

Continue? (y/N)
ステップ 5:削除の実行
# After confirmation
git branch -d <branch-name>  # For merged branches
git branch -D <branch-name>  # Force delete (unmerged)

ワークツリーがあるブランチの場合は、先にワークツリーを削除します。

# Check if branch has a worktree
git worktree list | grep "\\[$branch\\]"

# Remove worktree before deleting branch
git worktree remove --force /path/to/worktree
git branch -D <branch-name>

ワークツリーを処理しながら [gone] ブランチを一括削除する場合:

# Process all [gone] branches, handling worktrees automatically
git branch -v | grep '\[gone\]' | sed 's/^[+* ]//' | awk '{print $1}' | while read branch; do
  echo "Processing branch: $branch"
  # Find and remove worktree if it exists
  worktree=$(git worktree list | grep "\\[$branch\\]" | awk '{print $1}')
  if [ ! -z "$worktree" ] && [ "$worktree" != "$(git rev-parse --show-toplevel)" ]; then
    echo "  Removing worktree: $worktree"
    git worktree remove --force "$worktree"
  fi
  # Delete the branch
  echo "  Deleting branch: $branch"
  git branch -D "$branch"
done

コマンドリファレンス

# Bulk delete merged branches (excluding protected branches and current branch)
# Notes:
# - Uses for loop + case for bash/zsh compatibility (avoids `while IFS= read` issues in zsh).
# - Uses case statement for exact-name matching (avoids grep regex edge cases).
# - Always exclude the current branch to prevent accidental self-deletion.
BASE_BRANCH="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')"
[ -n "$BASE_BRANCH" ] || BASE_BRANCH=main
CURRENT_BRANCH="$(git branch --show-current)"
for branch in $(git branch --merged "$BASE_BRANCH" | sed 's/^[* ]*//'); do
  case "$branch" in
    main|master|trunk|develop|development|"$CURRENT_BRANCH"|"") continue ;;
    *) git branch -d "$branch" ;;
  esac
done

# Prune remote-tracking references (requires network access)
# Note: This may fail if offline or remote is unreachable.
# If it fails, skip this step - branch analysis still works with cached remote data.
git fetch --prune || echo "Warning: Could not reach remote. Using cached data."

# List oldest branches (30+ days)
git for-each-ref --sort=committerdate refs/heads/ \
  --format='%(committerdate:short) %(refname:short)' | head -20

# Worktree commands
git worktree list                              # List all worktrees
git worktree remove /path/to/worktree          # Remove a worktree
git worktree remove --force /path/to/worktree  # Force remove (even if dirty)
git worktree prune                             # Clean up stale worktree refs

ドライランモード

削除を実行せずにプレビューします。

# Preview only
BASE_BRANCH="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')"
[ -n "$BASE_BRANCH" ] || BASE_BRANCH=main
CURRENT_BRANCH="$(git branch --show-current)"
for branch in $(git branch --merged "$BASE_BRANCH" | sed 's/^[* ]*//'); do
  case "$branch" in
    main|master|trunk|develop|development|"$CURRENT_BRANCH"|"") ;;
    *) echo "$branch" ;;
  esac
done

ユーザーが「--dry-run」、「preview」、または「just show me」と指定した場合は、ドライランモードを実行します。

安全チェックリスト

削除する前に、以下を確認します。

  • 現在のブランチではない
  • 保護対象のブランチ(base/main/master/trunk/develop)ではない
  • プッシュされていないコミットがない(上流より先行していない)
  • (ブランチに関連付けられたワークツリーがある場合)先にワークツリーを削除済み
  • ユーザーの確認を得ている
安全性をすばやく確認するコマンド
# Show "ahead/behind" vs upstream for each local branch
git for-each-ref refs/heads \
  --format='%(refname:short)|%(upstream:short)|%(upstream:trackshort)|%(committerdate:relative)|%(contents:subject)' \
  --sort=-committerdate

# For a specific branch, confirm it's not ahead of upstream (if upstream exists)
# (Empty output => nothing unpushed)
git log --oneline @{u}..HEAD 2>/dev/null || echo "No upstream configured for this branch"

# Check if a branch has an associated worktree
# ('+' prefix in git branch -v output indicates worktree)
git branch -v | grep "^+" | awk '{print $2}'

# Find worktree path for a specific branch
git worktree list | grep "\\[branch-name\\]"

コメント