Skip to content

Instantly share code, notes, and snippets.

@tkatochin
Last active April 22, 2016 05:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkatochin/243c116d2798fafa7efbca2b7ab2ecd6 to your computer and use it in GitHub Desktop.
Save tkatochin/243c116d2798fafa7efbca2b7ab2ecd6 to your computer and use it in GitHub Desktop.
あるブランチの最後のコミットが、別のブランチにマージ済みかを判定するコマンド
#!/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
Copy link
Author

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

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

@tkatochin
Copy link
Author

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

@tkatochin
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment