リモートにプッシュしたブランチが、ローカル以外でリベースされたあとに master などにマージされた場合、その元となったローカルブランチは git branch --merged
しても表示はされませんが、もうマージされているので不要なブランチです。
Gitlab で MR を ff マージできるときしかマージしない設定をしていると(Merge commit with semi-linear history
)、プッシュしたあとに Gitlab 上でリベースしてからマージすることになるので、ローカルにこの種のブランチが残ってしまいます。
つまり、次のように B からブランチを生やした MR について。
ローカル以外で MR 先へリベースしたうえでマージされると、Y を指しているローカルブランチはマージ済なので削除して問題ありませんが git branch --merged
でもこれは表示されません。
あるブランチが master にマージされているか調べる方法
いくつか方法は考えられますが・・・
master にリベースして master と同じ位置に来るか見る。
git checkout feature-hoge
git rebase origin/master
# feature-hoge と origin/master が同じ位置なら feature-hoge は削除できます
git log --decorate --oneline --graph
マージしてみて差分があるか見る。
git checkout -B master origin/master
git merge --no-commit --no-ff feature-hoge
# 差分がなければ feature-hoge は削除できます
git status
# マージ途中状態なので abort しておきます
git merge --abort
あるブランチが master にマージされているか調べる方法:改
上の2つの方法はワーキングツリーやインデックスがいじられるので使いにくいです。次のようにすればワーキングツリーを弄らずに確認できます。
まず、マージ済か調べたいブランチと master の共通の祖先のコミットを得ます。
git merge-base feature-hoge master
そのコミットを用いた3方向マージの内容を表示します。
git merge-tree abc12345 feature-hoge master
これで何も表示されなければ feature-hoge は master へマージ済なので削除できます。また、git merge-tree
は表示するだけなのでワーキングツリーやインデックスを汚しません。
次のようなシェルスクリプトを作成して git ls-merged
とかで呼べるようにしておくと便利です。
#!/bin/bash
ref=${@:-HEAD}
git for-each-ref --format='%(refname:short)' refs/heads/ | while read -r x; do
if ! git merge-tree "$(git merge-base "$x" "$ref")" "$ref" "$x" 2>/dev/null | read -r; then
echo "$x"
fi
done