Gostaria de executar um teste de unidade antes de cada git push e se os testes falharem, cancele o push, mas não consigo nem encontrar o gancho de pré-push, há apenas pré-commit e pré-rebase.
Gostaria de executar um teste de unidade antes de cada git push e se os testes falharem, cancele o push, mas não consigo nem encontrar o gancho de pré-push, há apenas pré-commit e pré-rebase.
Respostas:
Eu prefiro executar o teste em um gancho de pré-confirmação. Porque a mudança já está registrada no momento da confirmação. Push e pull apenas trocam informações sobre as alterações já registradas. Se um teste falhar, você já terá uma revisão "quebrada" em seu repositório. Quer você esteja forçando ou não.
Git ganhou o pre-push
gancho no 1.8.2
lançamento.
pre-push
Script de amostra : https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
1.8.2 notas de versão falando sobre o novo gancho de pré-push: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
O Git ganhou o gancho pré-push na versão 1.8.2.
Pre-push hooks são o que eu precisava junto com os hooks pré-commit. Além de proteger um branch, eles também podem fornecer segurança extra combinada com ganchos pré-commit.
E para um exemplo de como usar (tomado, adotado e aprimorado a partir desta bela entrada )
Exemplo simples para fazer login no vagrant, executar testes e enviar
#!/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
Como você pode ver, o exemplo usa um galho protegido, assunto do gancho pré-push.
Se você estiver usando a linha de comando, a maneira mais fácil de fazer isso é escrever um script de push que execute seus testes de unidade e, se eles forem bem-sucedidos, conclua o push.
Editar
No git 1.8.2, essa resposta está desatualizada. Veja a resposta de manojlds acima.
Não há um gancho para isso, porque um push não é uma operação que modifica seu repositório.
Você pode fazer as verificações no lado receptor, no entanto, no post-receive
gancho. É aí que você geralmente rejeitaria um push recebido. A execução de testes de unidade pode ser um pouco trabalhosa para fazer em um gancho, mas isso é com você.
Para constar, há um patch para Git 1.6 que adiciona um gancho pré-push . Não sei se funciona contra 1,7.
Em vez de mexer com isso, você pode executar um script push como o recomendado pelo @kubi. Você também pode torná-la uma tarefa Rake para que fique em seu repo. ruby-git pode ajudar com isso. Se você verificar o repo de destino, poderá executar testes apenas ao enviar para o repo de produção.
Finalmente, você pode executar seus testes em seu pre-commit
gancho, mas verificar com qual branch está sendo comprometido. Então você poderia ter um, digamos, um production
branch que requer que todos os testes passem antes de aceitar um commit, mas você master
não se importa. limerick_rake pode ser útil nesse cenário.
O script vinculado pela resposta mais votada mostra os parâmetros etc para o pre-push
gancho ( $1
é o nome remoto, $2
URL) e como acessar os commits (linhas read
de stdin têm estrutura <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