はじめに
Git で作業しているとローカルブランチがどんどん増えていきます。
リモートブランチでマージされたブランチは削除してしまいたいのですが、その際ちょっと困った事象に直面しました。
直面した問題
git branch --merged
を実行しても、(マージされたはずの)ブランチが表示されない。
基本的には、master
or main
ブランチで git fetch
をして、git branch --merged
をすればマージされたブランチの一覧が表示されることが大半です。
その場合は、下記のコマンドでローカルブランチを削除できます。
git branch --merged | grep -v 'master' | xargs -I{} git branch -d {}
もしくは、
git fetch -p
# or
git fetch --prune
上記ではどうにもならない場合
今回の主題はこの部分です。
git branch --merged
がうまく効かない場合は、リモートブランチとローカルブランチの差分を検出して削除するという強引な方法で目的を達成できます。
結論を先に書くと、下記のコマンドです。
diff --changed-group-format='%<' --unchanged-group-format='' <(git branch | sed -e 's/^[ \*]*//') <(git branch -r | sed -e 's;^.*origin/;;g') | xargs -I{} git branch -d {}
なかなかクレイジーですね。中身をひとつひとつ見ていきます。
<(...)
は Process substitution と呼ばれ、コマンドの結果を file のように取り扱うことができます。
diff
コマンドのひとつ目の引数 git branch | sed -e 's/^[ \*]*//'
は、ローカルブランチの一覧を取得するコマンドです。
現在のブランチは *
で表示されるため、トリムしてブランチ名だけを取得しています。
ふたつ目の引数 git branch -r | sed -e 's;^.*origin/;;g'
は、リモートブランチの一覧を取得するコマンドです。不要となる余白と origin/
を取り除いています。
diff のオプションには --changed-group-format
と --unchanged-group-format
を適用しています。
--unchanged-group-format=''
で、共通で存在するブランチ名を非表示にします。
--changed-group-format='%<'
で、ローカルブランチの一覧に追加がある場合、ローカルブランチの一覧を表示します。
この二つのオプションを合わせることで、ローカルブランチにのみ存在するブランチ名称を取得できます。(push していないブランチなど)
おわりに
シェルを久しく触ってなかったの、シェル力がかなり落ちてました。
(元々そんなに高くないけど。。。)