
git fetch –pruneで解決!branch -rに残る削除済みリモートブランチの原因と直し方
チームで開発していて、誰かがリモートブランチを削除したのに、自分のローカルでは git branch -r を実行すると削除されたはずのブランチがまだ表示されている――そんな経験はないだろうか。
このページでは、削除済みリモートブランチがローカルに残り続ける仕組みの解説から、git fetch --prune を使った最も手軽な解決策、各ホスティングサービス(GitHub・GitLab・Bitbucket)での確認方法、再発防止の設定まで、一通りの対処法をまとめている。

この記事で解決できること
- ✅
git branch -rに削除済みのリモートブランチが表示され続ける原因が分かる - ✅
git fetch --pruneとgit remote prune originの使い分けが分かる - ✅ 自動 prune を有効化してこの問題を恒久的に防ぐ設定が分かる
- ✅ GitHub・GitLab・Bitbucket それぞれでリモートブランチの状態を確認する方法が分かる
動作確認環境: Linux / macOS / Windows(Git for Windows)/ Git 2.39 以上
問題の再現と確認
チームで開発中、同僚が feature/awesome-feature というブランチを GitHub 上で削除した。しかし自分のローカルで確認すると次のように残ったままになっている。
$ git branch -r
origin/HEAD -> origin/main
origin/main
origin/develop
origin/feature/awesome-feature ← 削除済みのはずなのに残っている
ここで削除しようと push を試みると次のエラーが出る。
$ git push origin :feature/awesome-feature
error: unable to delete 'feature/awesome-feature': remote ref does not exist
error: failed to push some refs to 'git@github.com:yourorg/yourrepo.git'
リモート上にはもう存在しないので当然のエラーだが、なぜローカルには残り続けるのかが分からず困る人が多い。
![]()
原因:リモートトラッキングブランチとは何か
Git の「リモートトラッキングブランチ」の仕組み
git branch -r で表示されるのはリモートトラッキングブランチと呼ばれるもので、.git/refs/remotes/ 以下にローカルキャッシュとして保存されている。
.git/
└── refs/
└── remotes/
└── origin/
├── main
├── develop
└── feature/awesome-feature ← ローカルに残ったキャッシュ
このキャッシュは git fetch を実行したときにリモートの最新状態と同期されるが、デフォルトでは「リモートで削除されたブランチを消す」動作は行われない。新しいブランチの追加や既存ブランチの更新は反映されるが、削除は反映されないのがデフォルトの挙動だ。
| 操作 | デフォルトの git fetch で反映されるか |
|---|---|
| リモートに新しいブランチが追加された | ✅ 反映される |
| リモートのブランチが更新(push)された | ✅ 反映される |
| リモートのブランチが削除された | ❌ 反映されない(デフォルト) |
これが「削除済みブランチがローカルに残り続ける」根本原因だ。
解決策1:git fetch --prune(最も手軽)
概要
--prune オプションを付けて fetch することで、リモートに存在しなくなったトラッキングブランチをローカルから削除できる。
# リモートの最新情報を取得しつつ、削除済みブランチのキャッシュを削除
$ git fetch --prune
# または短縮形
$ git fetch -p
実行例
$ git fetch --prune
From github.com:yourorg/yourrepo
- [deleted] (none) -> origin/feature/awesome-feature
[deleted] と表示され、削除済みブランチのトラッキング情報がローカルから除去される。
確認してみると:
$ git branch -r
origin/HEAD -> origin/main
origin/main
origin/develop
# feature/awesome-feature が消えた
注意:
git fetch --pruneはリモートトラッキングブランチ(origin/xxx)を消すだけで、ローカルブランチ(git branchで表示される方)は消えない。ローカルブランチが残っている場合は別途git branch -d ブランチ名で削除する。

解決策2:git remote prune origin
fetch は行わず、トラッキングブランチのクリーンアップだけ行いたい場合は git remote prune を使う。
# リモートの状態を確認しながらローカルの古いトラッキングブランチを削除
$ git remote prune origin
–dry-run で事前確認する
実際に削除する前に「何が消えるか」を確認できる。
$ git remote prune --dry-run origin
Pruning origin
URL: git@github.com:yourorg/yourrepo.git
* [would prune] origin/feature/awesome-feature
[would prune] と表示されたブランチが実際に削除される対象となる。問題なければ --dry-run なしで実行する。
git fetch --prune との使い分け
| コマンド | fetch も行う | ユースケース |
|---|---|---|
git fetch --prune |
✅ 行う | リモート最新化と同時にクリーンアップしたいとき(推奨) |
git remote prune origin |
❌ 行わない | fetch はせずクリーンアップだけしたいとき |
通常は git fetch --prune の方が一度でリモートの最新状態を反映できるため推奨。
解決策3:自動 prune を有効化して恒久的に防ぐ
毎回 --prune を付けるのを忘れそうな場合は、Git の設定で自動的に prune するよう設定できる。
グローバル設定(全リポジトリに適用)
$ git config --global fetch.prune true
設定後は、通常の git fetch を実行するだけで自動的に削除済みブランチがクリーンアップされるようになる。
リポジトリごとの設定
グローバルではなく特定のリポジトリのみに適用する場合:
# プロジェクトルートで実行
$ git config fetch.prune true
設定は .git/config に書き込まれる。
[remote "origin"]
url = git@github.com:yourorg/yourrepo.git
fetch = +refs/heads/*:refs/remotes/origin/*
prune = true ← これが追加される
チーム開発では全員がこの設定を入れると、「なんかブランチが増えてきた」問題が起きにくくなる。
GitHub・GitLab・Bitbucket での確認方法
GitHub でリモートブランチを確認する
GitHub のリポジトリページ → 「Branches」タブで現在存在するブランチの一覧が確認できる。
# GitHub API でリモートブランチ一覧を取得する場合
$ curl -s \
-H "Authorization: token YOUR_GITHUB_TOKEN" \
"https://api.github.com/repos/yourorg/yourrepo/branches" \
| jq '.[].name'
Pull Request をマージした後に「Delete branch」ボタンを押してもらう運用にすることで、未 prune のブランチが増えにくくなる。
GitLab でリモートブランチを確認する
# GitLab API でリモートブランチ一覧を取得
$ curl -s \
--header "PRIVATE-TOKEN: YOUR_GITLAB_TOKEN" \
"https://gitlab.com/api/v4/projects/YOUR_PROJECT_ID/repository/branches" \
| jq '.[].name'
GitLab では「マージリクエストのマージ時にブランチを削除」を設定できるため、活用することを推奨する。
Bitbucket でリモートブランチを確認する
# Bitbucket API でリモートブランチ一覧を取得
$ curl -s \
-u "YOUR_USERNAME:YOUR_APP_PASSWORD" \
"https://api.bitbucket.org/2.0/repositories/yourworkspace/yourrepo/refs/branches" \
| jq '.values[].name'
よくある関連エラーと対処法
ローカルブランチが残っている場合
git fetch --prune でリモートトラッキングブランチは消えるが、ローカルブランチは残ったままになる。これを一括削除するには以下の方法がある。
# リモートに存在しない(トラッキング先が消えた)ローカルブランチを確認
$ git branch -vv | grep ': gone]'
feature/awesome-feature abc1234 [origin/feature/awesome-feature: gone] Some commit message
# 該当ブランチを削除
$ git branch -d feature/awesome-feature
# マージ済みでない場合は強制削除
$ git branch -D feature/awesome-feature
一括で削除したい場合は以下のワンライナーが使える。
# 注意: 削除前に必ず git branch -vv | grep ': gone]' で確認すること
$ git fetch --prune && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d
注意:
xargs git branch -dはマージ済みブランチのみ削除する(未マージブランチはエラーになる)。強制削除は-Dに変更するが、作業中のコミットが失われる可能性があるため注意。
git fetch 自体がエラーになる場合
$ git fetch --prune
fatal: 'origin' does not appear to be a git repository
fatal: Could not read from remote repository.
この場合はリモートの設定が壊れているか、SSH キーの問題が考えられる。
# リモートURLを確認
$ git remote -v
# SSH接続を確認(GitHub の場合)
$ ssh -T git@github.com
まとめ
git branch -r に削除済みリモートブランチが残り続ける問題について解説した。
- 主な原因:
git fetchはデフォルトでリモートの削除をローカルに反映しない - 最短の解決策:
git fetch --prune(またはgit fetch -p)を実行する - 再発防止策:
git config --global fetch.prune trueを設定し、全 fetch で自動 prune を有効化する
削除済みのリモートトラッキングブランチはただのキャッシュなので、消しても問題ない。git remote prune --dry-run origin で事前確認してから実行すれば安心だ。
チームの全員が fetch.prune true を設定しておくと、積み重なって何十本もブランチが残るような状況を防げる。





ディスカッション
コメント一覧
このコマンドでごみブランチが表示されなくなりました。
ありがとうございまいた!