Git Post-Receive-Hook, um jeden Zweig in verschiedene Ordner auszuchecken?

Lesezeit: 4 Minuten

Git Post Receive Hook um jeden Zweig in verschiedene Ordner auszuchecken
Ben Frain

Die grundlegende Einrichtung unseres Git-Workflows ist ein reines Repository auf einem lokalen Netzwerkserver, auf das zwei Entwickler pushen/pullen.

Wir möchten jeden Zweig, der an einen anderen Ort auf unserem lokalen Netzwerkserver gepusht wird, automatisch kopieren (auschecken). Veranschaulichen:

Durch Pushen des „develop“-Zweigs werden Kopien in den „develop“-Unterordner kopiert. Durch Pushen des „Master“-Zweigs werden Kopien in den „Master“-Unterordner verschoben.

Das Problem, das wir haben, ist, den Post-Receive-Hook dazu zu bringen. Hier ist, was wir derzeit haben:

#!/bin/bash

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    GIT_WORK_TREE=/master
    git checkout -f $branch
    echo 'Changes pushed master.'
  fi

  if [ "develop" == "$branch" ]; then
    GIT_WORK_TREE=/develop
    git checkout -f $branch
    echo 'Changes pushed to develop.'
  fi
done

Der erhaltene Fehler ist:

‘remote: fatal: Dieser Vorgang muss in einem Arbeitsbaum ausgeführt werden. remote: Zur Entwicklung gedrängte Änderungen.’

Wie Sie es von diesem Fehler erwarten würden, wird tatsächlich nichts ausgecheckt.

Ich hatte auch den Post-Receive auf diese Weise versucht, aber das gleiche Problem:

#!/bin/bash

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    git --work-tree=/master checkout -f $branch
    echo 'Changes pushed master.'
  fi

  if [ "develop" == "$branch" ]; then
    git --work-tree=/develop checkout -f $branch
    echo 'Changes pushed to develop.'
  fi
done

Kann mir jemand erklären, was ich hier falsch mache (erklären Sie es gerne so, wie Sie es einem 3-Jährigen tun würden :)). Danke.

Um die Antwort für zukünftige Leser klarer zu machen, traf Torek auf den Kopf. Ich benutzte --work-tree=/master um zu versuchen, zu einem Ordner namens “Master” im Stammverzeichnis meines Bare-Repos zu gelangen (z. B. neben “Branches”, “Hooks” usw.). Sobald ich dies umgestellt habe --work-tree=./master (beachten Sie den Punkt vor dem Schrägstrich) alles funktionierte wie erwartet.

Sie sollten ‘GIT_WORK_TREE=/master git checkout -f $branch’ in eine Zeile einfügen, dann hat es funktioniert, nachdem Sie Ihren Beitrag gelesen haben, lautet mein Post-Receive:

#!/bin/sh

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    GIT_WORK_TREE=/home/tnj/www/www.test.com git checkout -f $branch
    chmod -R 775 /home/tnj/www/www.test.com/
    echo 'changes pushed to www.test.com'
  fi

  if [ "develop" == "$branch" ]; then
    GIT_WORK_TREE=/home/tnj/www/www.test.com.dev git checkout -f $branch
    chmod -R 775 /home/tnj/www/www.test.com.dev/
    echo 'changes pushed to www.test.com.dev'
  fi
done

hat geklappt, danke für deinen Beitrag! 🙂

Git Post Receive Hook um jeden Zweig in verschiedene Ordner auszuchecken
Torek

Du bekommst das, weil /master und /develop sind nicht vorhandene Verzeichnisse:

$ git --work-tree=/nonexistent checkout master
fatal: This operation must be run in a work tree

Vielleicht möchten Sie auch meine Antwort auf eine Frage zu einem anderen Problem sehen, das bei diesem Ansatz auftritt, das auch einen kleinen Fehler behebt, den Sie von einer beliebten, aber falschen Post-Receive-Technik kopiert haben (die Verwendung von cut um die aktualisierte Referenz zu analysieren).

[Your phrasing also makes me wonder if you are thinking of deploying those two branches into a sub-directory within the (presumably --bare) repository that is receiving the pushes. This is probably not a great idea.]

Eine andere (andere) Methode zum Bereitstellen besteht darin, einen „echten“ Git-Baum am Bereitstellungsort zu haben. Dann statt git --work-tree=... checkout du machst stattdessen so etwas:

deploy()
{
    local path=$1 branch=$2

    (cd $path && unset GIT_DIR && git fetch && git checkout -f origin/$branch)
}

(ungetestet, fühlen Sie sich frei zu experimentieren und/oder zu modifizieren). Dies hat andere, etwas andere Kompromisse in Bezug auf Speicherplatz und Aktualisierungsfenster (die ich in der anderen Antwort erwähne).

  • torek, verzeihen Sie meine grundlegenden Fragen. Die Ordner „master“ und „develop“ existieren, aber ich zweifle nicht daran, dass ich Dinge missverstehe. Grundsätzlich muss ich Dateien von einem Zweig zu einem Serverstandort und die Dateien von einem anderen zu einem anderen kopieren. Ich hatte Unterordner des ursprünglichen Bare-Repos als Ziel verwendet, nur um es zum Laufen zu bringen, aber es klingt, als hätten Sie eine bessere Idee. Mit dem deploy() Snippet, das Sie bereitgestellt haben – würde das in den Post-Receive-Hook gehen? Entschuldigung für die grundlegenden Fragen, aber das geht mir im Moment alles zu weit.

    – Ben Frain

    9. Oktober 13 um 13:13 Uhr

  • Sie verwenden weiterhin das Wort “Ordner”, verwenden Sie ein System vom Typ Nicht-Unix/Linux? Beachten Sie, dass /xxx bezeichnet eine Datei oder ein Verzeichnis im Stammverzeichnis, kein Unterverzeichnis (“Unterordner”) von irgendetwas anderem. (Um ein Unterverzeichnis von „hier“ zu benennen, verwenden Sie ./xxx zum Beispiel. Aber in einem nackten Repo, das direkt in den privaten Speicherbereich von git schreibt, daher “keine gute Idee”: Sie könnten versehentlich etwas Wichtiges für git überschreiben.) Wie für deploy: Folgen Sie dem Link, dort ist ein Skript, das für jemand anderen mit einem ähnlichen Setup funktioniert.

    – Torek

    9. Oktober 13 um 13:33 Uhr


.

561820cookie-checkGit Post-Receive-Hook, um jeden Zweig in verschiedene Ordner auszuchecken?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy