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 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.
Ich stimme im Allgemeinen zu, obwohl dies unpraktisch sein kann, wenn Sie die Gewohnheit haben, später viele inkrementelle Zusagen zum Squash zu machen, und die Testsuite groß ist.
Cascabel
Aha. Daher würde ich vorschlagen, dass die Tests vor dem Zusammenführen mit dem Hauptzweig ausgeführt werden, aber es gibt auch keinen Hook vor dem Zusammenführen. Es gibt jedoch einen "Update" -Hook, mit dem verhindert werden kann, dass eine Referenz im Remote-Repository aktualisiert wird: "Kurz vor der Aktualisierung der Referenz im Remote-Repository wird der Update-Hook aufgerufen. Sein Exit-Status bestimmt den Erfolg oder Misserfolg der Referenz update. Der Hook wird einmal für jede zu aktualisierende Referenz ausgeführt und verwendet drei Parameter: den Namen der zu aktualisierenden Referenz, den in der Referenz gespeicherten alten Objektnamen und den in der Referenz zu speichernden neuen Objektnamen. "
Besitzwidrig
18
Abgestimmt, weil es - obwohl informativ - die Frage des OP völlig ignoriert.
Der Dembinski
1
@ TheDembinski Ich würde nicht sagen, dass es die OP-Frage ignoriert. Tatsächlich berücksichtigt es dies und sagt, dass es einen besseren Weg gibt, dies zu tun, als es das OP im Sinn hatte. Das ist im Allgemeinen die Art von Antwort, die ich gerne bekommen würde.
calder.ty
9
@ calder.ty - Nein. Manojlds spricht besser an, worauf es ankommt. In der Tat sind Pre-Commit-Hooks, die Tests ausführen, im Allgemeinen eine schlechte Idee. Es wird davon ausgegangen, dass alle Dinge, die festgeschrieben werden, Tests bestehen müssen. Das ist schlecht für gängige Arbeitsabläufe, die sich auf die Zusammenarbeit konzentrieren. Also ja ... ich bin anderer Meinung; Es ist weder ein besserer Weg, "es" zu tun, noch geht es auf die Frage ein.
Der Dembinski
209
Git hat den pre-pushHaken in der 1.8.2Veröffentlichung.
@manojlds Weißt du, wofür dieser Haken gedacht ist? Ich möchte es verwenden, um meine Binärdatei an meine Kunden zu senden, wenn sie in einen bestimmten Zweig verschoben wird (dh die nächtliche Version erstellen und mit Curl hochladen, bevor sie gesendet wird). Das Problem ist, dass das Erstellen und Hochladen eine Weile dauert und die Remote-Verbindung geschlossen wird. Am Ende habe ich meine Binärdatei erstellt und an Kunden hochgeladen, aber nicht in ein Repo verschoben, da das Remote-Repo die Verbindung schließt. Irgendeine Idee, wie man das umgehen kann? Oder vielleicht ist es eine schlechte Idee in seiner Wurzel.
Igrek
@igrek Haben Sie eine Lösung für das Problem beim Schließen der Verbindung gefunden?
Mario Estrada
1
@MarioEstrada, ja, ich weiß nicht genau, wie, aber ich habe es zweimal pushen lassen: Der erste git-Befehl führt Unit-Tests aus und wenn er nicht getrennt wird, pusht er und startet einen weiteren Push in einem anderen Thread, wenn der erste puscht raus, der zweite aus einem anderen Thread funktioniert für mich. Wenn entweder der erste oder der zweite erfolgreich ist, drückt der erste auf Änderungen und der zweite auf nichts. Der Trick ist, dass ich einige Argumente hinzugefügt habe, die Unit-Tests umgehen (die für den zweiten Git-Push verwendet wurden, so dass Unit-Tests nicht erneut gestartet wurden)
igrek
24
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 [email protected] -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.
Meinst du, überhaupt keine Haken zu benutzen? Ersetzen Sie einfach "git pull" durch "git uinttestspull". das ist nicht genau das, was ich brauche
Schafwanderer
1
@sheepwalker: s / pull / push / und benutze einen Alias, um es schön kurz zu machen.
Cascabel
@sheepwalker Ja, das ist nicht genau das, wonach Sie gefragt haben, aber wie @calmh sagte, gibt es keine Pre-Push-Haken.
Kubi
8
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-receiveHook 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.
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-commitHook ausführen, aber prüfen, für welchen Zweig ein Commit ausgeführt wird. Dann könnten Sie beispielsweise einen productionZweig haben, für den alle Tests bestanden werden müssen, bevor ein Commit akzeptiert wird, aber es ist Ihnen masteregal. limerick_rake kann in diesem Szenario nützlich sein.
#!/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
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.
quelle
Git hat den
pre-push
Haken in der1.8.2
Veröffentlichung.Beispielskript
pre-push
: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample1.8.2 Versionshinweise zum neuen Pre-Push-Hook: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
quelle
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
Wie Sie sehen können, verwendet das Beispiel einen geschützten Zweig, der Gegenstand des Pre-Push-Hakens ist.
quelle
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.
quelle
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.quelle
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 einenproduction
Zweig haben, für den alle Tests bestanden werden müssen, bevor ein Commit akzeptiert wird, aber es ist Ihnenmaster
egal. limerick_rake kann in diesem Szenario nützlich sein.quelle
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 (Zeilenread
von stdin haben Struktur<local ref> <local sha1> <remote ref> <remote sha1>
)quelle