機能ブランチを使い捨てで開発していると、PRがマージされたあとに残った不要ブランチがリポジトリに積み重なっていきます。整理せずに放置すると、ブランチ一覧が見づらくなるだけでなく、「このブランチ、まだ使ってるんだっけ?」という混乱を招き、誤った派生元の選択につながることもあります。ブランチ削除は日常的に行う定番メンテナンス作業です。
この記事では、Gitでブランチを削除する方法を体系的にまとめます。ローカルブランチ・リモートブランチ・リモート追跡ブランチの3種類の違い、-dと-Dの安全性、一括削除テクニック、削除前のマージ状況確認、そして誤って消してしまったときの救済まで、チーム開発で迷わない実践的な使い方を解説します。
この記事で学べること
- Gitの3種類のブランチ(ローカル/リモート/リモート追跡)の違いと削除コマンドの対応
git branch -d(安全削除)と-D(強制削除)の違い- リモートブランチを削除する
git push --deleteの使い方 - ローカルに残るリモート追跡ブランチの整理(
fetch --prune) - マージ済みブランチだけを一括削除する安全なテクニック
- 現在チェックアウト中のブランチを削除するケースへの対応
- 誤って消した場合の
reflogによる復元手順
まず整理:Gitには3種類のブランチがある
「ブランチを削除する」といっても、対象は3つあります。混同すると「削除したはずなのに消えていない」「共有リモートからだけ消したかったのにローカルも消した」といった事故が起きるため、最初に整理しておきましょう。
ポイント:多くの場合はローカルブランチとリモートブランチの両方を削除し、pruneで追跡情報も整理する3ステップがセットです。いきなりgit branch -dだけでは不完全——リモートに同名ブランチが残っていれば再度pullで戻ってくる、といった混乱の原因になります。
ローカルブランチを削除する(-d / -D)
自分の手元にあるブランチの削除はgit branch -dが基本です。-d(小文字)は未マージの変更がないかチェックして安全に削除、-D(大文字)は問答無用で強制削除します。
# 安全削除(マージ済みのみ消せる) git branch -d feature/login # マージ済みでないとエラーになる # error: The branch 'feature/login' is not fully merged. # If you are sure you want to delete it, run 'git branch -D feature/login'. # 強制削除(未マージでも消す) git branch -D feature/login # 複数ブランチを一度に削除 git branch -d feature/login feature/logout feature/register # 削除成功時の出力 # Deleted branch feature/login (was a1b2c3d).
注意:-Dで強制削除した未マージコミットは、reflog期限(既定90日)内ならSHAを特定して復旧できますが、reflogにない共有メンバーのコミットは見つけづらくなります。削除前にgit log <branch> ^mainで「このブランチ固有のコミット」が何か確認する習慣を付けましょう。
現在チェックアウト中のブランチは消せない
# 現在のブランチ確認 git branch --show-current # mainなど別ブランチに切り替え git switch main # あとは通常どおり削除 git branch -d feature/login
削除時にエラーが出る場合の原因と対処は【Git】ブランチが削除できないときの原因と対処法に詳しくまとめています。
リモートブランチを削除する(push –delete)
GitHub/GitLab等のリモートにあるブランチを削除するにはgit push --deleteを使います。ローカルとは別の操作で、リモートから物理的に削除する唯一の方法です。
# origin のブランチを削除 git push origin --delete feature/login # 古い短縮記法(同じ意味) git push origin :feature/login # → 「空を feature/login にpush」=削除 # 複数のリモートブランチを同時に削除 git push origin --delete feature/login feature/logout # 削除成功時の出力 # To github.com:user/repo.git # - [deleted] feature/login
削除順序のおすすめ
- 先にリモートブランチを削除(チームへの影響を減らすため)
- 次にローカルの同名ブランチを削除
- 最後に
git fetch --pruneで追跡情報を整理 - GitHubのPR画面からは「Delete branch」ボタンでリモート削除が可能
禁止:保護ブランチ(main/develop/masterなど)への削除pushは厳禁です。GitHubのBranch protection rulesで物理的に禁止する設定が入っていることが多く、入っていなければ今すぐ設定しましょう。誤削除した場合の復旧は誤ってmaster/mainを削除したときの復旧方法を参照。
リモート追跡ブランチを整理する(prune)
リモート側でブランチが削除されても、ローカルのorigin/xxx追跡情報は自動では消えません。残りっぱなしになるとgit branch -aで存在しないブランチが表示され続け、混乱の元になります。
# fetch と同時に prune(推奨) git fetch --prune # 全リモートに対して一括で git fetch --all --prune # prune だけを単独実行 git remote prune origin # 何が削除されるかだけ確認(dry-run) git remote prune origin --dry-run # 毎回prune するように自動化 git config --global fetch.prune true
「削除したはずのリモートブランチがまだ見える」場合の詳細はリモートブランチを削除しても残ってしまうときの原因と解決方法、リモート情報の確認方法はリモートブランチを確認する方法を参照してください。
削除前の安全確認:マージ状況とコミット内容
削除する前に「このブランチ固有のコミットが本当にマージされているか」を確認する習慣を付けると作業の消失事故を防げます。
# mainにマージ済みのローカルブランチを一覧 git branch --merged main # 未マージのローカルブランチを一覧 git branch --no-merged main # リモートも含めて確認 git branch -a --merged main git branch -a --no-merged main # 特定ブランチがmainに含まれるか確認 git merge-base --is-ancestor feature/login main && echo "merged" # このブランチ固有のコミット数を確認 git log --oneline main..feature/login
PR運用の確認ポイント
- GitHubのPRがMergedになっている(Closedだけでは危険)
- squash merge・rebase mergeの場合、
--merged判定にかからないことがある - 不安なら
git log --oneline main..<branch>で固有コミットが空か確認 - squash時は内容ベースのチェック(同じ修正がmainにあるか)を目視で
注意:squash mergeやrebase mergeで取り込まれた機能ブランチは、Gitの履歴上は「マージされていない」扱いになります。そのためgit branch -dで拒否されることがあります。内容が取り込まれていることを確認のうえ、-Dで強制削除するのが現実的な運用です。
一括削除:マージ済みブランチをまとめて整理
機能ブランチが数十個溜まってしまったときは、--mergedと組み合わせた一括削除が便利です。
# mainにマージ済みのローカルブランチを全削除(main/developを除外)
git branch --merged main | grep -vE "^\*|^[[:space:]]*(main|master|develop)$" | xargs git branch -d
# より安全に:対象一覧を先に確認
git branch --merged main | grep -vE "^\*|^[[:space:]]*(main|master|develop)$"
# パターンマッチで削除
git branch | grep "feature/archived-" | xargs git branch -D
# リモートの削除済みを全部prune
git fetch --all --prune
# goneマークのついたローカルブランチを整理(リモートが既に削除済み)
git branch -vv | grep ": gone]" | awk '{print $1}' | xargs -r git branch -D
注意:パイプで一括削除する前に必ずdry run(対象一覧表示)で想定通りのブランチが含まれているか確認してください。xargs -I{} echo "would delete: {}"のように置き換えると安全です。main/master/developは明示的に除外する正規表現に入れておきましょう。
goneブランチの一掃
git branch -vvで[origin/xxx: gone]と表示されるブランチは、リモートで削除済みだけどローカルに残っている状態です。これらは安全に-Dできます。
# gone の一覧
git branch -vv | grep ": gone]"
# 一括削除(事前にリストを確認してから)
git branch -vv | grep ": gone]" | awk '{print $1}' | xargs git branch -D
# エイリアス登録しておくと便利
git config --global alias.prune-gone "\!git branch -vv | grep ': gone]' | awk '{print \$1}' | xargs -r git branch -D"
git prune-gone
誤って削除したブランチの復旧
ローカルブランチを消してしまっても、git reflogでSHAを特定すれば90日以内なら高確率で復旧できます。
# 削除時に表示されたSHAがあれば直接 # Deleted branch feature/login (was a1b2c3d). ← このa1b2c3dを使う # 表示を逃した場合はreflogを確認 git reflog # ブランチを復元 git branch feature/login a1b2c3d # 切り替えもしたい場合 git switch feature/login # もしくはswitchで一発(-cは同等の挙動) git switch -c feature/login a1b2c3d
リモートブランチを誤削除した場合
# 自分のローカルにそのブランチが残っていれば再push git push -u origin feature/login # ローカルにもない場合:他メンバーに依頼してpushしてもらう # 誰も持っていない場合:GitHubの管理画面やEvents APIから探す # (深刻な場合はGitHub Supportに問い合わせ)
ポイント:マージ済みブランチの削除なら、削除してもコミット自体は本流にあるので消えません。「ブランチ名ラベル」が外れただけで、履歴自体はgit log --all --onelineなどで辿れます。本当に困るのは未マージブランチを-Dで強制削除した場合のみです。
main/masterを消してしまった最悪ケースは誤ってmaster/mainを削除したときの復旧方法で詳細な手順を解説しています。
チーム運用のベストプラクティス
ブランチ削除のルーチン化
- PRマージ時にリモート自動削除:GitHubで「Automatically delete head branches」を有効化
- fetch.prune = true:常に追跡情報を自動整理(前述)
- 週1回のメンテナンス:
git fetch --all --prune+gone削除を習慣化 - 保護ブランチ設定:main/developには削除禁止ルールを適用
- 命名規則:
feature/・hotfix/・release/等の接頭辞で管理しやすく - 削除前にはPR確認:squash/rebase mergeに該当しないか要チェック
GUI・IDEでの削除方法
コマンドだけでなくGUIツールでもブランチ削除ができます。
主要ツールでの削除
- VS Code / Cursor:Source ControlパネルのBranches→右クリック→
Delete Branch - JetBrains(IntelliJ/WebStorm):Gitツールウィンドウ→Branches→ブランチ右クリック→
Delete - SourceTree:左サイドバーのBranches→右クリック→
Delete(Force Delete可) - GitHub Desktop:Current Branch→Manage Branches→ブランチ選択→Delete
- GitHub Web:PRページの
Delete branchボタン、Branchesページから一括整理
やってはいけない落とし穴
ローカルを消せばリモートも消えると思う
git branch -dはローカルブランチだけを削除します。リモート側のブランチは別のコマンド(git push --delete)が必要です。GitHub等で削除したつもりがリモートに残っており、他メンバーがその古いブランチを再度pullして混乱、というパターンは頻出事故です。
git branch -d origin/xxx で消せると思う
これはローカルのリモート追跡情報を消すだけで、リモート本体には何も影響しません。結果としてgit fetchで再度origin/xxxが戻ってきます。リモートブランチを本当に消したいならgit push origin --delete xxxが正解です。
-D を気軽に使う
-Dは未マージコミットも強制削除します。自分だけが作業したブランチなら問題ありませんが、チームで共同作業していたブランチを誤って強制削除すると他メンバーの作業が消えるリスクがあります。基本は-dで安全確認→必要なら-Dという流れが健全です。
squash/rebase mergeされたブランチが未マージ扱いになる
GitHubのsquash merge/rebase mergeでPRを取り込んだ場合、機能ブランチのコミット履歴とmainの履歴は別のSHAになるため、git branch --mergedでは「未マージ」と判定されます。内容が取り込まれていることを確認したうえで-Dで削除するのが実用的です。PRページでMergedのラベルが付いているかをまず確認しましょう。
削除後のgoneブランチを放置する
リモートで削除されたブランチの追跡情報がローカルに残り続けると、git branch -aやgit checkoutの補完で不要なブランチが表示されます。リモート側で削除を行ったら必ずgit fetch --pruneで整理しましょう。fetch.prune = true設定で自動化するのが理想です。
よくある質問
-d(小文字)で安全に削除し、マージ済みでないと怒られたらsquash merge等で取り込み済みかPRで確認→-Dで強制削除、という流れが安全です。初手から-Dを使う癖は避けましょう。git push origin --delete <name>を使います。GitHubならPRマージ後の「Delete branch」ボタン、Branchesページの一括削除UIも便利です。ローカルとは別操作なので、両方必要です。git switch mainなど別ブランチに移動してから削除します。移動時に「ファイルが壊れる」エラーが出る場合はgit stashで退避してから切り替えてください。git reflogでSHAを探し、git branch <name> <SHA>またはgit switch -c <name> <SHA>で復元できます。90日以内ならほぼ確実に救済可能です。git branch --merged main | grep -vE "^\*|main|master|develop" | xargs git branch -dでマージ済みをまとめて削除できます。事前に--merged単独で対象一覧を確認してから実行してください。git fetch --pruneでリモート追跡を整理し、git branch -vv | grep ": gone]" | awk '{print $1}' | xargs git branch -Dでローカルのgoneブランチを一掃できます。fetch.prune = trueで自動化も可能です。関連記事
- 【Git】ブランチが削除できないときの原因と対処法 — エラー別のトラブルシューティング
- 【Git】リモートブランチを削除しても残ってしまうときの原因と解決方法 — pruneの詳細解説
- 【Git】誤ってmaster/mainを削除したときの復旧方法 — 保護ブランチ消失時の復旧
- 【Git】ブランチ名を変更する方法 — 削除せずに改名したい場合
- 【Git】新しいブランチを作成する基本的な手順 — 作成の基礎
- 【Git】リモートブランチを確認する方法 — branch -a / ls-remote 等の確認コマンド
- 【Git】ブランチ名を変更したらpushできなくなったときの対処法 — リネーム後のpushエラー
- Gitで過去のコミットから新しいブランチを作り作業をやり直す方法 — 派生ブランチ作成
まとめ
- Gitには3種類のブランチ(ローカル/リモート/追跡)があり、削除コマンドも別々
- ローカル削除は
git branch -d(安全)/-D(強制) - リモート削除は
git push origin --delete <name> - 追跡情報の整理は
git fetch --prune、自動化はfetch.prune=true - 一括削除は
--mergedと組み合わせるが、dry-run確認が必須 - squash/rebase mergeは
--merged判定にかからないので要注意 - 誤削除は
reflog→git branch <name> <SHA>で90日以内なら復旧可 - 保護ブランチ(main/develop)は必ずBranch protection rulesで削除禁止に
ブランチ削除は地味ですが、リポジトリを清潔に保つために欠かせない作業です。「ローカル削除→リモート削除→prune」のセットで覚え、GitHubの自動削除設定と組み合わせて日常的に整理する習慣を付けましょう。削除時に万一ミスがあってもreflogで救済できるので、必要以上に怖がらず、正しい手順で安全にブランチ管理を進めていきましょう。

