Zum Inhalt springen
>_marc-oltersdorf.de

Git: post-receive-Hook erstellen, der nach dem Push in den Webordner ausliefert

Marc Oltersdorf 3 Min. Lesezeit aktualisiert 18.10.2026

Ein post-receive-Hook sorgt dafür, dass der Git-Server nach jedem Push die Dateien automatisch in den Webordner auscheckt. Dafür reicht ein kleines Skript im hooks-Verzeichnis des Repositorys, das Zielpfad, Git-Verzeichnis und Branch festlegt – und das ausführbar sein muss.

$ git log --graph Der Weg zur Lösung

  1. Problem Nach jedem Push von Hand auschecken

    Das bare repository auf dem Server nimmt Pushes an, aber der Webordner bleibt, wie er ist. Jemand muss nachziehen – und vergisst es.

  2. Erkenntnis Git ruft nach dem Push selbst ein Skript auf

    Der Hook post-receive läuft nach jedem angenommenen Push. Mit --work-tree und --git-dir kann er aus dem bare repository in einen fremden Ordner auschecken.

  3. Lösung Hook anlegen und ausführbar machen

    Sechs Zeilen Skript im hooks-Ordner, chmod +x – seitdem landet jeder Push auf dem Branch direkt im Webordner.

Ein Git-Server nimmt Pushes entgegen, aber die Dateien landen nicht von allein im Webordner. Wer nach jedem Push von Hand in den Zielordner wechselt und auscheckt oder gar per FTP kopiert, vergisst das irgendwann – und liefert einen alten Stand aus. Die Lösung ist ein post-receive-Hook: ein kleines Skript im Repository, das Git nach jedem angenommenen Push aufruft und das den gewünschten Branch direkt in den Webordner auscheckt.

Das Problem

Das Repository auf dem Server ist ein bare repository (ein Ordner wie project.git ohne eigene Arbeitskopie). Ein Push aktualisiert dort nur die Verwaltungsdaten; im Webordner, den der Webserver ausliefert, ändert sich nichts. Es fehlt der Schritt, der nach dem Push die Dateien des Branches an die richtige Stelle bringt – automatisch, ohne dass jemand daran denken muss.

Den Hook anlegen

Wir erstellen im hooks-Ordner des entsprechenden Repositorys eine Datei mit dem Namen post-receive:

sudo vi /pfad/zum/git/project.git/hooks/post-receive

Diese füllen wir mit folgendem Inhalt:

#!/bin/bash
TARGET="/pfad/zum/webordner/project"
GIT_DIR="/pfad/zum/git/project.git"
BRANCH="master"

echo "Push zum Webordner"
git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH

TARGET ist der Webordner, GIT_DIR das Repository, BRANCH der Branch, dessen Stand ausgeliefert werden soll.

Ausführbar machen

Danach müssen wir die Datei noch ausführbar machen – sonst ignoriert Git den Hook stillschweigend:

sudo chmod +x /pfad/zum/git/project.git/hooks/post-receive

Warum das funktioniert

Git führt Skripte aus dem Ordner hooks zu festen Zeitpunkten aus. post-receive läuft auf dem Server, nachdem ein Push vollständig angenommen wurde – einmal je Push, egal wie viele Branches darin stecken. Was das Skript auf die Standardausgabe schreibt, sieht der Pushende in seinem Terminal, jeweils mit remote: davor; das echo im Skript ist also eine kleine Erfolgsmeldung.

Die beiden Optionen --work-tree und --git-dir trennen Arbeitskopie und Repository. Normalerweise liegen beide zusammen in einem Ordner; hier liegt das Repository als bare repository an einer Stelle und der Webordner an einer anderen. So kann Git den Branch in einen beliebigen Ordner auschecken, ohne dass dort ein .git-Verzeichnis entsteht. checkout -f erzwingt den Stand des Branches und überschreibt Änderungen, die jemand direkt im Webordner gemacht hat – gewollt, denn der Webordner ist kein Arbeitsplatz, sondern das Ziel.

Stolperfallen

  • Nicht ausführbar: Ohne chmod +x passiert nichts, und Git meldet auch keinen Fehler. Wenn der Push durchgeht, aber im Webordner nichts ankommt, zuerst hier nachsehen.
  • Falscher Branch-Name: Heißt der Hauptbranch main statt master, schlägt der Checkout mit einer Meldung wie pathspec 'master' did not match fehl – sichtbar in der Push-Ausgabe hinter remote:.
  • Zielordner und Rechte: Der Webordner muss existieren, und der Benutzer, der den Push entgegennimmt (meist der SSH-Benutzer des Git-Servers), braucht dort Schreibrechte. Gehört der Ordner dem Webserver-Benutzer, hilft eine gemeinsame Gruppe.
  • Jeder Push löst aus: Das Skript prüft nicht, welcher Branch gepusht wurde. Auch ein Push auf einen Feature-Branch checkt den in BRANCH eingetragenen Stand erneut aus – harmlos, aber gut zu wissen.
  • Handänderungen gehen verloren: Wegen -f verwirft der Checkout alles, was jemand direkt im Webordner geändert hat. Konfigurationsdateien und Uploads, die nicht ins Repository gehören, deshalb außerhalb des Webordners ablegen oder per .gitignore ausnehmen – ignorierte Dateien lässt der Checkout in Ruhe.

Hat dir das geholfen?

RSS abonnieren

$ ls ../ Passt dazu

6 min

PowerShell-Skripte umsortieren, ohne Aufrufer zu brechen: Weiterleitung am alten Pfad, die mitschreibt

Ein gewachsener Skriptordner auf einer Freigabe sollte neu sortiert werden, aber niemand wusste, welche geplanten Aufgaben, Monitoring-Sensoren und Verknüpfungen die Skripte über ihren Pfad aufrufen. Statt eines Stichtags bleibt an jedem alten Pfad eine kleine Weiterleitung liegen, die den Aufrufer protokolliert und das Skript am neuen Ort startet. Nach ein paar Tagen zeigt das Protokoll, was umgestellt werden muss.

4 min

Outlook-Warnung „Ein Programm versucht, auf E-Mail-Adressinformationen zuzugreifen“ abschalten – und was man dabei riskiert

Programme wie Greenshot, die per COM eine Mail in Outlook anlegen, lösen auf Servern und Rechnern ohne erkannten Virenschutz regelmäßig eine Zugriffswarnung aus. Per Gruppenrichtlinie lässt sie sich gezielt abschalten – damit darf dann aber jedes Programm in der Sitzung ohne Rückfrage Adressen lesen und Mails versenden.

5 min

Greenshot: Export nach Outlook zeigt nur wieder das Menü (TYPE_E_CANTLOADLIBRARY)

Greenshot bietet Outlook als Ziel an, beim Auswählen erscheint aber nur wieder das Menü. Im Log steht TYPE_E_CANTLOADLIBRARY: Die COM-Registrierung von Outlook ist defekt. Handarbeit in der Registry half nicht, die Onlinereparatur entfernte Office sogar – erst eine Neuinstallation per Office Deployment Tool mit dem richtigen Update-Kanal löste das Problem.