回答:
私はむしろテストをpre-commit-hookで実行したいと思います。コミット時に変更がすでに記録されているためです。プッシュおよびプルは、すでに記録された変更に関する情報のみを交換します。テストが失敗した場合、リポジトリにはすでに「壊れた」リビジョンがあります。それを押しているかどうか。
Gitはリリースでpre-push
フックを取得し ました1.8.2
。
サンプルpre-push
スクリプト:https : //github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
1.8.2新しいプレプッシュフックについてのリリースノート:https : //github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Gitは1.8.2リリースでpre-pushフックを取得しました。
事前プッシュフックは、事前コミットフックと共に必要なものです。ブランチを保護するだけでなく、プリコミットフックと組み合わせて追加のセキュリティを提供することもできます。
そして、使用方法の例として(この素晴らしいエントリから採用され、拡張されました)
vagrantにログインし、テストを実行してからプッシュする簡単な例
#!/bin/bash
# Run the following command in the root of your project to install this pre-push hook:
# cp git-hooks/pre-push .git/hooks/pre-push; chmod 700 .git/hooks/pre-push
CMD="ssh vagrant@192.168.33.10 -i ~/.vagrant.d/insecure_private_key 'cd /vagrant/tests; /vagrant/vendor/bin/phpunit'"
protected_branch='master'
# Check if we actually have commits to push
commits=`git log @{u}..`
if [ -z "$commits" ]; then
exit 0
fi
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [[ $current_branch = $protected_branch ]]; then
eval $CMD
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "failed $CMD"
exit 1
fi
fi
exit 0
ご覧のとおり、例ではpre-pushフックの対象である保護されたブランチを使用しています。
コマンドラインを使用している場合、これを行う最も簡単な方法は、ユニットテストを実行するプッシュスクリプトを記述し、成功した場合はプッシュを完了することです。
編集する
git 1.8.2以降、この回答は古くなっています。上記のmanojldsの回答を参照してください。
記録として、プレプッシュフックを追加するGit 1.6のパッチがあります。それが1.7に対して機能するかどうかはわかりません。
それを台無しにするのではなく、@ kubi推奨のようなプッシュスクリプトを実行できます。代わりにRakeタスクにすることもできるので、リポジトリにあります。ruby-gitはこれに役立ちます。ターゲットリポジトリをチェックすると、本番リポジトリにプッシュするときにのみテストを実行できます。
最後に、pre-commit
フックでテストを実行し、どのブランチがコミットされているかを確認できます。次に、たとえば、production
コミットを受け入れる前にすべてのテストに合格する必要があるが、master
気にしないブランチを持つことができます。limerick_rakeはそのシナリオで役立つ場合があります。
高投票回答によってリンクされたスクリプトに示したパラメータなどpre-push
のフックは($1
リモートの名前であり、$2
そしてどのように(行のコミットにアクセスするためのURL)read
の構造を有する標準入力から<local ref> <local sha1> <remote ref> <remote sha1>
)
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
if [ "$remote_sha" = $z40 ]
then
# New branch, examine all commits
range="$local_sha"
else
# Update to existing branch, examine new commits
range="$remote_sha..$local_sha"
fi
# Check for WIP commit
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
if [ -n "$commit" ]
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0