Ich möchte vor jedem Git-Push einen Unit-Test durchführen. Wenn der Test fehlschlägt, brechen Sie den Push ab, aber ich kann nicht einmal einen Pre-Push-Hook finden. Es gibt nur Pre-Commit und Pre-Rebase.
Ich möchte vor jedem Git-Push einen Unit-Test durchführen. Wenn der Test fehlschlägt, brechen Sie den Push ab, aber ich kann nicht einmal einen Pre-Push-Hook finden. Es gibt nur Pre-Commit und Pre-Rebase.
Antworten:
Ich würde den Test lieber in einem Pre-Commit-Hook ausführen. Weil die Änderung bereits beim Festschreiben aufgezeichnet wird. Push and Pull tauschen nur Informationen über bereits aufgezeichnete Änderungen aus. Wenn ein Test fehlschlägt, haben Sie bereits eine "defekte" Revision in Ihrem Repository. Ob Sie es schieben oder nicht.
Git hat den pre-push
Haken in der 1.8.2
Veröffentlichung.
Beispielskript pre-push
: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
1.8.2 Versionshinweise zum neuen Pre-Push-Hook: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Git hat den Pre-Push-Hook in der Version 1.8.2 bekommen.
Pre-Push-Hooks waren genau das, was ich brauchte, zusammen mit Pre-Commit-Hooks. Neben dem Schutz eines Zweigs können sie auch zusätzliche Sicherheit in Kombination mit Pre-Commit-Hooks bieten.
Und für ein Beispiel zur Verwendung (aus diesem schönen Eintrag übernommen und übernommen und erweitert )
Einfaches Beispiel, um sich bei Vagrant anzumelden, Tests durchzuführen und dann zu pushen
#!/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
Wie Sie sehen können, verwendet das Beispiel einen geschützten Zweig, der Gegenstand des Pre-Push-Hakens ist.
Wenn Sie die Befehlszeile verwenden, können Sie dies am einfachsten tun, indem Sie ein Push-Skript schreiben, das Ihre Komponententests ausführt und bei Erfolg den Push abschließt.
Bearbeiten
Ab Git 1.8.2 ist diese Antwort veraltet. Siehe die Antwort von manojlds oben.
Es gibt keinen Hook dafür, da ein Push keine Operation ist, die Ihr Repository ändert.
Sie können die Überprüfungen jedoch auf der Empfangsseite im post-receive
Hook durchführen. Dort lehnen Sie normalerweise einen eingehenden Push ab. Das Ausführen von Komponententests ist möglicherweise etwas intensiv, aber das liegt bei Ihnen.
Für die Aufzeichnung gibt es einen Patch zu Git 1.6, der einen Pre-Push-Hook hinzufügt . Ich weiß nicht, ob es gegen 1.7 funktioniert.
Anstatt sich damit herumzuschlagen, könnten Sie ein Push-Skript ausführen, wie es @kubi empfohlen hat. Sie können es stattdessen auch zu einer Rake-Aufgabe machen, damit es in Ihrem Repo ist. Ruby-Git könnte dabei helfen. Wenn Sie das Ziel-Repo überprüfen, können Sie Tests nur ausführen, wenn Sie zum Produktions-Repo wechseln.
Schließlich können Sie Ihre Tests in Ihrem pre-commit
Hook ausführen, aber prüfen, für welchen Zweig ein Commit ausgeführt wird. Dann könnten Sie beispielsweise einen production
Zweig haben, für den alle Tests bestanden werden müssen, bevor ein Commit akzeptiert wird, aber es ist Ihnen master
egal. limerick_rake kann in diesem Szenario nützlich sein.
Das Skript, das durch die hoch bewertete Antwort verknüpft ist, zeigt die Parameter usw. des pre-push
Hooks ( $1
ist Remote-Name, $2
URL) und wie auf die Commits zugegriffen wird (Zeilen read
von stdin haben 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