Odpowiedzi:
Wolałbym raczej uruchomić test w haku poprzedzającym zatwierdzenie. Ponieważ zmiana jest już rejestrowana podczas zatwierdzania. Push and pull tylko wymiany informacji o już zarejestrowanych zmianach. Jeśli test się nie powiedzie, będziesz mieć już „zepsutą” wersję w swoim repozytorium. Niezależnie od tego, czy to naciskasz, czy nie.
Git dostał pre-push
haczyk w 1.8.2
wydaniu.
Przykładowy pre-push
skrypt: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
Informacje o wydaniu 1.8.2 mówiące o nowym haku przed wypychaniem: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Git uzyskał hak przed wypychaniem w wersji 1.8.2.
Haczyki przed wypychaniem są tym, czego potrzebowałem wraz z hakami przed zatwierdzeniem. Oprócz ochrony gałęzi mogą również zapewnić dodatkowe bezpieczeństwo w połączeniu z haczykami pre-commit.
I na przykład, jak używać (wzięte i przyjęte i ulepszone z tego fajnego wpisu )
Prosty przykład logowania się do włóczęgi, uruchamiania testów, a następnie wypychania
#!/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
Jak widać, w przykładzie zastosowano chronioną gałąź, temat haka pre-push.
Jeśli korzystasz z wiersza poleceń, najłatwiejszym sposobem na to jest napisanie skryptu wypychania, który uruchamia testy jednostkowe i, jeśli się powiedzie, kończy wypychanie.
Edytować
Od wersji 1.8.2 git ta odpowiedź jest nieaktualna. Zobacz odpowiedź manojlds powyżej.
Nie ma na to punktu zaczepienia, ponieważ wypychanie nie jest operacją modyfikującą repozytorium.
Możesz jednak zrobić kontrole po stronie odbiorczej, na post-receive
haku. To jest miejsce, w którym zwykle odrzucasz nadchodzący atak. Wykonywanie testów jednostkowych może być trochę intensywne, ale to zależy od Ciebie.
Dla przypomnienia, istnieje łatka do Git 1.6, która dodaje hak przed wypychaniem . Nie wiem, czy działa przeciwko 1.7.
Zamiast zadzierać z tym, możesz uruchomić skrypt push, taki jak zalecany @kubi. Możesz także uczynić z tego zadanie Rake, aby znalazło się w twoim repozytorium. ruby-git może w tym pomóc. Jeśli sprawdzisz repozytorium docelowe, możesz uruchomić testy tylko podczas wypychania do repozytorium produkcyjnego.
Na koniec możesz uruchomić testy w swoim pre-commit
hooku, ale sprawdź, do której gałęzi jest przypisana. Wtedy możesz mieć, powiedzmy, production
gałąź, która wymaga przejścia wszystkich testów przed zaakceptowaniem zatwierdzenia, ale ciebie master
to nie obchodzi. limerick_rake może być przydatny w tym scenariuszu.
Skrypt związany przez wysoko głosowało odpowiedź pokazuje parametry itp do pre-push
haka ( $1
jest odległa nazwisko, $2
adres URL) i jak uzyskać dostęp do zobowiązuje (linie read
ze standardowego wejścia mają strukturę <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