no7.space
🧹

ローカルの Git でマージ済みのブランチを削除する

issue ベースでトピックブランチ切りながら開発を行っていると、手元には push 済みのブランチが大量に残ることになります

$git branch
develop
feature/34
feature/35
feature/36
feature/39
feature/45
main
...

トピックブランチは、作業が終わってマージされたら基本的に不要になるので消したくなるわけですが、
まとめて消す方法って無いっぽくて、溜め込みすぎると消すのも一苦労です。

ということでまとめて消す方法を考えます。

マージ済みブランチを探す

git branch でブランチを表示できますが、このとき --merged オプションをつけてあげると、マージ済みのブランチのみに絞ることができます

git branch --merged
feature/34
feature/36
feature/39

この人たちはマージ済みなので消しても大丈夫です。

ブランチを削除する

ブランチ削除のオプションは2つあります

git branch -d ${branch_name}
git branch -D ${branch_name}

オプションの D が大文字か小文字かの違いなのですが、
-d と小文字で書くと、マージ済みの場合のみ削除できます。なので間違ってマージ前ブランチを指定してもエラーで止まってくれます。
逆に -D と大文字で書くと、マージ済みかどうかにかかわらずブランチが削除されます。危険ではありますが、何らかの理由でしかかりのブランチを削除したくなったときはこれが有効です。

今回はマージ済みのブランチを消すのが目的なので、使うコマンドは前者が最適ですね。

一括削除するためのコマンドを作る

Git には、パスの通った場所に git-からはじまる実行可能なスクリプトをおいておくことで、それを Git のサブコマンドのように実行できる仕組みがあります。

たとえば /usr/local/bin/git-foobar.sh ってファイルがあった場合、

git foobar

って感じで実行できます。
なのでこの仕組みを使ってオリジナルのサブコマンドを実装していきます。

git-delete-merged-branch という名前でファイルを作成して以下のようにします。

#!/bin/sh
# マージ済みブランチの削除
PROTECTED_BRANCHES='master|main|develop|development'
git branch --merged | egrep -v "\*|${PROTECTED_BRANCHES}" | xargs git branch -d

1行目のシェバンは、環境に合わせて調整してください。

type sh

とかすればわかるはず。

出来上がったら、実行権限をつけて、パスの通ったところに移動するか、適当な場所に設置したうえでパスの通った場所にシンボリックリンクを貼ります。
私はターミナル関連は全部 ~/dotfiles にまとめて Git 管理してるのでそこに置いてます。

cd /PATH/TO/git-delete-merged-branch
chmod +x git-delete-merged-branch
ln -s $(pwd)/git-delete-merged-branch /usr/local/bin/git-delete-merged-branch

あとは、シェルを再起動するなどしてあげれば delete-merged-branch という git のサブコマンド風なオリジナルコマンド が使えるようになります。

git delete-merged-branch
Deleted branch feature/34 (was a0d6069).
Deleted branch feature/36 (was 1c7968d).
Deleted branch feature/39 (was de6f0c3).

シェルスクリプト名は git-delete-merged-branch ですが、実際に呼ぶときは git delete-merged-branch となることに注意です。
とはいえ、git-delete-merged-branch というスクリプトがパスの通った場所にあるのでまぁどっちでも多分動く気はしますが…… 💦

参考