詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

Gitでマージ済みのブランチを一括削除する

こうしてます。

git for-each-ref --merged HEAD --no-contains HEAD 'refs/heads/**' --format '%(refname)' \
  | while read s; do echo "$s $(git rev-parse "$s")"; git update-ref -d "$s"; done

git branch を使ったやり方が一般的なようだが(Google調べ)、配管(Plumbing)コマンドを使って厳密にやるならこうでしょう。

git for-each-ref はリポジトリのrefを一覧するコマンド。refs/heads/** はいわゆるローカルブランチにマッチするパターン。--merged HEAD で現在のブランチであるHEADにマージ済みのブランチを、--no-contains HEAD でそのうちHEADを除いたものを一覧する。

--format %(refname) はrefの名前(refs/heads/branch-a など)を出力するので、これでHEADにマージ済みのブランチの一覧を出力してくれる。これをパイプで受け取ってブランチを削除したいわけだけど、refs/heads/branch-a のように完全修飾された名前は git branch -d に渡せないので、低レイヤの git update-ref を使って削除する。というわけ。

git for-each-ref には出力をシェルスクリプト向けにエスケープする --shell オプションもあるのだけど、git check-ref-format によればrefに改行などの特殊な文字は入らないっぽいのでこのやり方でいいはず。

はてなで一緒に働きませんか?