Réponses:
Je préférerais exécuter le test dans un pré-commit-hook. Parce que le changement est déjà enregistré lors de la validation. Push and pull échange uniquement des informations sur les modifications déjà enregistrées Si un test échoue, vous auriez déjà une révision "cassée" dans votre référentiel. Que vous le poussiez ou non.
Git a obtenu le pre-push
crochet dans la 1.8.2
version.
Exemple de pre-push
script: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
1.8.2 Notes de version parlant du nouveau hook pré-push: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Git a obtenu le hook pre-push dans la version 1.8.2.
Les hooks pré-push sont ce dont j'avais besoin avec les hooks pré-commit. Outre la protection d'une branche, ils peuvent également fournir une sécurité supplémentaire combinée à des hooks de pré-validation.
Et pour un exemple d'utilisation (repris et adopté et amélioré à partir de cette belle entrée )
Exemple simple pour se connecter à vagrant, exécuter des tests, puis pousser
#!/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
Comme vous pouvez le voir, l'exemple utilise une branche protégée, objet du crochet de pré-poussée.
Si vous utilisez la ligne de commande, le moyen le plus simple de le faire est d'écrire un script push qui exécute vos tests unitaires et, s'ils réussissent, termine le push.
Éditer
Depuis git 1.8.2, cette réponse est obsolète. Voir la réponse de manojlds ci-dessus.
Il n'y a pas de hook pour cela, car un push n'est pas une opération qui modifie votre référentiel.
Vous pouvez cependant faire les vérifications du côté de la réception, dans le post-receive
crochet. C'est là que vous rejetteriez généralement une poussée entrante. L'exécution de tests unitaires peut être un peu intensive à faire dans un hook, mais c'est à vous de décider.
Pour mémoire, il existe un patch pour Git 1.6 qui ajoute un hook pré-push . Je ne sais pas si cela fonctionne contre 1.7.
Plutôt que de jouer avec ça, vous pouvez exécuter un script push comme @kubi recommandé. Vous pouvez également en faire une tâche Rake à la place pour qu'elle soit dans votre dépôt. ruby-git pourrait vous aider. Si vous vérifiez le dépôt cible, vous ne pouvez exécuter des tests que lors de la transmission vers le dépôt de production.
Enfin, vous pouvez exécuter vos tests dans votre pre-commit
hook mais vérifiez dans quelle branche est validée. Ensuite, vous pourriez avoir une, disons, une production
branche qui exige que tous les tests réussissent avant d'accepter un commit, mais master
cela ne vous dérange pas. limerick_rake peut être utile dans ce scénario.
Le script lié par la réponse hautement votée montre les paramètres, etc. au pre-push
hook ( $1
est le nom distant, l' $2
URL) et comment accéder aux commits (les lignes read
de stdin ont une structure <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