Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
あるブランチの最後のコミットが、別のブランチにマージ済みかを判定するコマンド
#!/bin/sh
if [ $# != 2 -o "$1" = "$2" ]; then
echo "Usage ${0##*/} branch1 branch2"
echo ""
echo "branch2の中に、branch1の最後のコミットが含まれているか(マージ済みか)を判定します。"
echo "以下はリモートのdevelopブランチにローカルのdevelopブランチの最後のコミットが含まれているかを判定する例です。"
echo "例) ${0##*/} develop origin/develop"
echo ""
echo "実行直後、\$? で判定結果が得られます。"
echo " 0 : マージされていないか、branch2の示すブランチが無いかコミットログがありません。"
echo " 1 : マージされています。"
echo " -1 : branch1のコミットログは存在しません。"
echo " -2 : branch1のコミットログの出力結果が本コマンドの想定外の内容です。"
echo "注)"
echo "本コマンドはbranch1の最後のコミットだけを見ます。branch1のブランチ全てがbranch2にマージ済みであることを保証するものではありません。"
echo "例えばbranch2がbranch1が見える場所にありcherry-pickしただけかもしれない可能性も考慮して利用してください。"
fi
left_branch=$1
right_branch=$2
input_pattern_file=/tmp/search.txt
picked_result_file=/tmp/result.txt
err_echo () {
echo $1 1>&2
}
clean_end () (
if [ -f $input_pattern_file ]; then
rm $input_pattern_file
fi
if [ -f $picked_result_file ]; then
rm $picked_result_file
fi
unset left_branch
unset right_branch
unset input_pattern_file
unset picked_result_file
unset author
unset date_line
unset cnt
exit $1
)
#ローカル側の最後のコミットログをコミットIDを取り除いて取得
git log --name-status -n1 $left_branch > $input_pattern_file
line_count=`cat $input_pattern_file | wc -l`
if [ $line_count = 0 ]; then
err_echo "$left_branch のコミットログは存在しません."
clean_end -1
fi
exclude_commitid_line_count=`expr $line_count - 1`
tail -n $exclude_commitid_line_count $input_pattern_file > ${input_pattern_file}_temp
mv ${input_pattern_file}_temp $input_pattern_file
#その中のAuthorの内容を取得
author=
date_line=
cnt=0
while read line; do
cnt=`expr $cnt + 1`
case $cnt in
1 ) author=${line#Author: } ;;
2 ) date_line=${line} ;;
esac
if [ $cnt = 2 ]; then
break
fi
done < $input_pattern_file
if [ "$author" = "" -o "$date_line" = "" ]; then
err_echo "Author: またはDate: がコミットログに含まれていません。git logコマンドの出力結果が想定外の結果です。"
cat $input_pattern_file 1>&2
clean_end -2
fi
#もう一方のログからAuthor指定で取得
git log --name-status --author="$author" $right_branch | grep -m 2 -B 1 -A `expr $line_count - 3` -F "$date_line" | head -n `expr $line_count - 1` > $picked_result_file
diff_result=`diff $input_pattern_file $picked_result_file | wc -l`
if [ $diff_result == 0 ]; then
# right_branchにはleft_branchがマージ済み
clean_end 1
else
# right_branchにはleft_branchはマージ済みではない
clean_end 0
fi
@tkatochin

This comment has been minimized.

Copy link
Owner Author

commented Apr 20, 2016

次のケースではマージ済みなのにマージされていないと判断されちゃいますけどあしからず。

  • branch1先頭コミットと同じ修正がbranch2の修正ログ内に既に存在してスキップされた場合
  • branch1先頭コミットがbranch2に入る際にコンフリクトがあってコメントやファイルが修正されてしまっていた場合
@tkatochin

This comment has been minimized.

Copy link
Owner Author

commented Apr 20, 2016

同じものが2回以上マージされているケースがあったので、最初のマッチ分だけ取得するようにした。
-m と -a の組み合わせが非道いから -m 1 とはできず2件まで取って head で1件分だけ削り取って解決。

@tkatochin

This comment has been minimized.

Copy link
Owner Author

commented Apr 22, 2016

バグってた〜。right_branchを指定してなかった。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.