大量のブランチをworktreeも考慮しながら一気に掃除できるコマンドを整備した

最近はCodex Appを使ったworktreeでの開発を活発にやるようになってきている。ブランチが大量に作られるというのはworktreeの活用で更に加速している。
ブランチの掃除は以前作ったコマンドを使っていたのだけれど、worktreeで使っているブランチには+が付与され、上手く使えなくなっていたので重い腰を上げて改善した。

前提

  • fish
  • Git 2.23.0以上
    • %(worktreepath) を利用するため
  • カレントブランチが基準となる
  • ローカルブランチのみが対象

元のコマンドとその問題点

alias gitprune='git branch --merged | egrep -v "^\*|^\+|main|master|develop|staging" | xargs git branch -d'

よく使う大事なブランチは除いて、マージ済みのものを git branch -d で削除するというもの。

しかし、 worktree を多用するようになってから、 git branch の結果に + とか入るようになり、そこでエラーになるようになってしまった。

Codexが挙げてくれたもの その1

function gitprune
    git branch --merged \
        | grep -Ev '^[*+]' \
        | grep -Ev '^[[:space:]]*(main|master|develop|staging)$' \
        | xargs git branch -d
end

マージ済みのブランチから * とか + を除外するのがポイント。(*がカレントブランチで、+がworktreeで使っているブランチ)
以下のような時にうまく除外してくれる。

  • + develop
  • main

一応これで解決できる。

Codexが挙げてくれたもの その2

git for-each-ref でGitの情報を直接使う方法

function gitprune
    for branch in (git for-each-ref refs/heads/ \
        --merged=HEAD \
        --format='%(if)%(worktreepath)%(then)%(else)%(refname:short)%(end)' \
        | string match -rv '^(|main|master|develop|staging)$')

        git branch -d $branch
    end
end

見た目は少し複雑になったのだけど、gitのコマンドで出力フォーマットを指定できるものがあり、それを使ってシンプルに出力することで xargs も使わず、コマンドの出力をシンプルに使う形になる。

また、worktreepathでworktreeの情報もちゃんと使えるのもいい点。
一方色々書いてあるので、純粋に分かりづらい。

また、最終コミットが30日以上前みたいなカスタマイズもしやすくなるとあったけど、やるかなぁ?というのが正直なところ。

まとめ

worktreeの件も解消しつつコマンドを整理できた。

シンプルに解決するなら前者。もう少しカスタマイズするなら多分後者。