Lokaler Ausführungshaken nach einem Git-Push?

71

Ich habe mir die Githooks-Manpage angesehen, aber wenn mir nichts fehlt, sehe ich keine Option für lokale Git-Hooks nach dem Push. Ich hätte gerne eine, die die API-Dokumente auf meinem Webserver aktualisiert (für die ich bereits ein Skript habe), nachdem ich den Hauptzweig auf das GitHub-Repo verschoben habe. Natürlich könnte ich einfach mein eigenes Skript schreiben, das den Git-Push und die API-Dokumente kombiniert, aber das fühlt sich etwas unelegant an.

Scotchi
quelle
Die post-updateHooks können für diesen Fall ausgelöst werden, oder?
Agnibha

Antworten:

10

Ab Git 1.8.2 wird vor dem Push-Vorgang ein neuer Hook aufgerufen: Pre-Push Wenn das Skript einen anderen Wert als 0 zurückgibt, wird der Push-Vorgang abgebrochen.

Erwähnen Sie in den Versionshinweisen: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt#L167

Beispiel: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample

Adrián Deccico
quelle
41
Ich glaube nicht, dass diese Antwort die gute ist, sie erzählt vom Pre-Push-Haken und die ursprüngliche Frage war vom Post-Push-Haken.
Levente Holló
3
Levente Holló, der Pre-Push-Hook wird ausgeführt, nachdem der Benutzer ausgeführt wurde git-pushund bevor Git das Commit / s tatsächlich pusht. In Git ist kein anderer Push-bezogener Hook integriert.
Adrián Deccico
54

Eine andere Lösung für dieses Problem besteht darin, einen Wrapper für git pushdie Ausführung .git/hooks/pre-pushund .git/hooks/post-pushSkripte vor und nach dem git pushAufruf zu haben. Ein möglicher Wrapper könnte folgendermaßen aussehen:

#!/bin/sh

GIT_DIR_="$(git rev-parse --git-dir)"
BRANCH="$(git rev-parse --symbolic --abbrev-ref $(git symbolic-ref HEAD))"

PRE_PUSH="$GIT_DIR_/hooks/pre-push"
POST_PUSH="$GIT_DIR_/hooks/post-push"

test -x "$PRE_PUSH" &&
    exec "$PRE_PUSH" "$BRANCH" "$@"

git push "$@"

test $? -eq 0 && test -x "$POST_PUSH" &&
    exec "$POST_PUSH" "$BRANCH" "$@"

Als git-push-whirgendwo in Ihrem gespeichert PATH, kann es dann aufgerufen werden, als git push-whob Sie mit Haken schieben möchten.

Frank S. Thomas
quelle
3
Das ist großartig ... Ich verwende separate Fernbedienungen: eine, in der ich meinen Code hoste , ein nacktes Repo auf meinem Produktionsserver, also habe ich diesen Code zu meiner ~ / .functions.sh hinzugefügt und verwende ** Push Origin ** ** Push-Produktion ** Es startet automatisch die Website (da dies in Push-Post definiert ist) in meinem Browser, sobald der Push abgeschlossen ist. Vielen Dank!
Saifur Rahman Mohsin
Der aktuelle Code funktioniert nicht in Git-Arbeitsbäumen. Um dies zu beheben, ändern Sie einfach 3 Zeilen: `GIT_DIR _ =" $ (Git-Rev-Parse - Git-Pfad-Hooks) "PRE_PUSH =" $ {GIT_DIR _} / Pre-Push "POST_PUSH = "$ {GIT_DIR _} / post-push" `
KaszpiR
36

Ich bin kürzlich auf dasselbe Problem gestoßen. Ich wollte einen Hook, damit ein Push von meinem Git-Submodul die neue Submodulreferenz im 'Superprojekt' festschreibt.

Wie Chris bereits erwähnt hat, ist der beste Weg, einfach einen Git-Alias ​​wie folgt zu verwenden:

$ git config alias.xpush '!git push $1 $2 && update-server.sh'
# (remember the backslash before the ! if your shell requires it)

Dadurch wird Ihrer .git / config-Datei Folgendes hinzugefügt:

[alias]
  xpush = !git push $1 $2 && update-server.sh

Und jetzt, wenn Sie Folgendes eingeben:

$ git xpush

Ihre Änderungen werden gepusht und dann wird update-server.sh ausgeführt.

ndbroadbent
quelle
3
Umm was ist, wenn Sie in einer Niederlassung sind? und du machst das xpush? sollte nicht so etwas wie! git push $ 1 $ 2 && update-server.sh sein, damit Sie den Ursprungszweig angeben können?
Jlbelmonte
Beachten Sie, dass das Überschreiben eines vorhandenen Befehls mit einem Git-Alias ​​nicht möglich ist, siehe stackoverflow.com/questions/3538774/…
brillout
36

Diese Art von Hook wird von Git nicht unterstützt. Es liegt außerhalb der gültigen Gründe für einen Git-Hook, wie sie vom Git-Betreuer angegeben wurden.

Die einleitende Bemerkung in der oben verlinkten Nachricht spricht fast direkt Ihren Fall an:

Ich mag keine Hooks, die nach einer lokalen Initiierung einer Operation wirken und ausschließlich auf lokale Daten reagieren. Dies liegt vielleicht daran, dass ich Git-Tools-Bausteine ​​immer noch mehr als andere Leute für Skripte auf höherer Ebene halte.

PS Ein "Single Push" -Tipp

  • Es gibt zu viele Vorbehalte für eine vollständige Erklärung, aber wenn Sie alles herausfinden können, sollten Sie in der Lage sein, mit den Details umzugehen.

Ein Extra pushurlzu einem lokalen Repo mit einem "alternativen" Objektspeicher kann Ihnen einen geringen Overhead bieten, um einen Push-Hook lokal auszuführen. Aber wirklich, der Aufwand ist viel mehr als git push upstream && update-web-server(vielleicht in einem Shell-Alias, Git-Alias ​​oder Skript).

Chris Johnsen
quelle
3
Die gleichen Informationen finden Sie unter: permalink.gmane.org/gmane.comp.version-control.git/71069
Jakub Narębski
2
Bitte beachten Sie, dass Git ab 1.8.2 einen Pre-Push- Hook hinzugefügt hat . Überprüfen Sie meine Antwort, um weitere Informationen zu finden.
Adrián Deccico
3

Ich benutze eine Funktion dafür:

current_branch() {
    local ref=$(git symbolic-ref HEAD 2> /dev/null) || return
    echo ${ref#refs/heads/}
}

gp() {
    local post_push="$(git rev-parse --git-dir)/hooks/post-push"
    git push "$@" && {
        [[ -x "$post_push" ]] && "$post_push" "$(current_branch)" "$@"
    }
}
compdef _git gp=git-push

Der compdef-Teil ist für ZSH.

pschmitt
quelle