「gitpush」中に追加されたすべてのリビジョンを抽出し、それぞれに対して何らかの処理(通知メールの送信など)を行うgitpost-receiveフックがあります。これは、マージする場合を除いてうまく機能します。例えば:
- branch1でいくつかのコミットを行い、次にbranch1をプッシュします。受信後フックはコミットを正しく処理します。
- branch1をbranch2にマージしてから、branch2をプッシュします。受信後フックは、マージされたすべてのコミットを2回処理します。
どうすればこれを回避できますか?以下は、処理する必要のあるコミットを抽出する受信後フックの始まりです(最後に、$ COMMITSは処理するコミットのリストを保持します)。
#!/bin/sh
REPO_PATH=`pwd`
COMMITS=''
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# for each ref that was updated during the push
while read OLD_REV NEW_REV REF_NAME; do
OLD_REV="`git rev-parse $OLD_REV`"
NEW_REV="`git rev-parse $NEW_REV`"
if expr "$OLD_REV" : '0*$' >/dev/null; then
# if the branch was created, add all revisions in the new branch; skip tags
if ! expr "$REF_NAME" : 'refs/tags/' >/dev/null; then
REF_REV="`git rev-parse $REF_NAME`"
REF_NAME="`git name-rev --name-only $REF_REV`"
COMMITS="$COMMITS `git rev-list $REF_NAME | git name-rev --stdin | grep -G \($REF_NAME.*\) | awk '{ print $1 }' | tr '\n' ' '`"
fi
elif expr "$NEW_REV" : '0*$' >/dev/null; then
# don't think branch deletes ever hit a post-receive hook, so we should never get here
printf ''
else
# add any commits in this push
COMMITS="$COMMITS `git rev-parse --not --all | grep -v $(git rev-parse $REF_NAME) | git rev-list --reverse --stdin $(git merge-base $OLD_REV $NEW_REV)..$NEW_REV | tr '\n' ' '`"
fi
done