git でメインラインのブランチが複数あるときに特定のブランチから分岐しているブランチを得る

Git でメインラインのブランチが複数あるとき(例えば main とか develop とか、あるいは v1.x とか v2.x とか)、特定のメインラインのブランチから分岐しているブランチを一覧表示する方法。

git branch --merged の反対をやるイメージですが、分岐元のメインラインのブランチが別の機能ブランチのマージにより進んでいることも考慮する必要があるため、単純にはできません。

手順

メインラインのブランチが A と B の 2 つあるときに、B から分岐しているブランチを一覧表示させます。

まず、A には含まれるものの B には含まれないコミットをすべてリストアップします。

git log A..B --format=%H

そしてそれらのコミットのいずれかを含むブランチをすべて表示します。

| xargs -i git br -r --contains {}

重複を除外すれば、目的とするブランチの一覧になります。

| sort | uniq

コマンドを繋げると次の通りです。

git log A..B --format=%H | xargs -i git br -r --contains {} | sort | uniq

メインラインが3つ以上あるときは次のようにすれば OK です。

# A にも B にもなくて C にだけあるコミットのいずれかを含むブランチのリスト
git log ^A ^B C --format=%H | xargs -i git br -r --contains {} | sort | uniq

# これでも OK です
git log C --not A B --format=%H | xargs -i git br -r --contains {} | sort | uniq

さいごに

Git flow とかで develop からたくさん機能ブランチが生えてる状態で、本番にデプロイ済の main/master ブランチからもホットフィックスブランチをたくさん生え、かつ、ホットフィックスブランチに命名規則的なものが無いために develop から生えた機能ブランチと区別がつかなくなったときに、この方法でどちらに属するブランチなのかを調べられます。