
Matt
Ich versuche, Git zum Staging meiner Website einzurichten, damit ich das kann git pull
um die aktuelle Version lokal zum Laufen zu bringen und dann git push
um die Änderungen auf den Remote-Server zu übertragen. Ich habe es so eingerichtet, dass es so funktioniert, wie ich es möchte, aber nachdem ich es gedrückt habe, muss ich es manuell ausführen git checkout -f
oder git reset --hard HEAD
auf dem Remote-Server.
Ich habe versucht, diese in ein Shell-Skript als Post-Receive-Hook auf dem Server einzufügen, aber es scheint einfach keine Wirkung zu haben. Ich weiß, dass das Skript ausgeführt wird, weil ich nach dem Push “Änderungen auf den Server übertragen” sehe. Hier ist der Post-Receive-Hook:
#!/bin/sh
git reset --hard HEAD
echo "Changes pushed to server."

Paul
Die Antwort auf deine Frage ist hier: http://toroid.org/ams/git-website-howto
Kurz gesagt, Sie möchten dem Bare-Repository einen “separaten Arbeitsbaum” hinzufügen. Normalerweise stellen Sie sich vor, dass Ihr Arbeitsbaum die enthält .git
Verzeichnis. Bare-Repositorys haben per Definition keinen Arbeitsbaum, aber Sie können einen erstellen, solange er sich in einem anderen Verzeichnis als das Bare-Repository befindet.
Der Post-Receive-Hook ist nur ein einfacher git checkout -f
um die des Repositorys zu replizieren HEAD
ins Arbeitsverzeichnis. Apache verwendet dies als Dokumentstammverzeichnis, und Sie sind fertig. Jedes Mal, wenn Sie in das Bare-Repository pushen, beginnt Apache sofort damit, es bereitzustellen.
Ich verwende dies im Allgemeinen, um automatisch auf einen Staging-Server zu pushen, um zu sehen, ob die “echte” Umgebung auf meine Änderungen kotzt. Die Bereitstellung auf dem Live-Server ist eine ganz andere Geschichte. 🙂

VonC
Aktualisierung März 2015
Wie ich in “Was ist diese Git-Warnmeldung beim Pushen von Änderungen an ein Remote-Repository?” erwähnt habe, können Sie tatsächlich pushen direkt jetzt zu einem nicht-nackten Repo (Git 2.3.0+, Februar 2015) mit:
git config receive.denyCurrentBranch updateInstead
Aktualisieren Sie den Arbeitsbaum entsprechend, aber verweigern Sie dies, wenn es nicht festgeschriebene Änderungen gibt.
Auf diese Weise können Sie jeden Post-Receive-Hook vermeiden.
(Ursprüngliche Antwort: Okt. 2010)
Die GitFAQ empfiehlt für Nicht-nacktes Repo dieser Post-Update-Hook:
(Es könnte Ihnen mehr Hinweise darauf geben, was tatsächlich bei der Hook-Ausführung vor sich geht. Beachten Sie, dass dies ein Post-Update-Hook ist, kein Post-Receive)
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
is_bare=$(git-config --get --bool core.bare)
if [ -z "$is_bare" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f $GIT_DIR/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached [email protected]{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git-update-ref --no-deref HEAD [email protected]{1}
cd $GIT_WORK_TREE
git stash save "dirty $desc before update to $new";
git-symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd $GIT_WORK_TREE
git-diff-index -R --name-status HEAD >&2
git-reset --hard HEAD)
}
if [ "$is_bare" = "false" ]
then
active_branch=`git-symbolic-ref HEAD`
export GIT_DIR=$(cd $GIT_DIR; pwd)
GIT_WORK_TREE=${GIT_WORK_TREE-..}
for ref
do
if [ "$ref" = "$active_branch" ]
then
update_wc $ref
fi
done
fi
Damit dies funktioniert, müssten Sie dennoch ausdrücklich zulassen, dass Änderungen an den aktuellen Zweig übertragen werden, indem Sie eine der folgenden Konfigurationseinstellungen verwenden:
git config receive.denyCurrentBranch ignore
oder
git config receive.denyCurrentBranch warn

ich mache
Ich hatte genau das gleiche Problem. In einer Antwort auf diesen Link: http://toroid.org/ams/git-website-howto – Folgender Befehl hat es geschafft:
sudo chmod +x hooks/post-receive
Wir haben eine verpasst sudo
Berechtigung konfigurierte zuerst das Zeug.
Feste Version des Skripts von VonC, funktioniert für mich (absolut keine Garantien).
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
set -e
git update-server-info
is_bare=$(git config --get --bool core.bare)
if [ -z "${is_bare}" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f ${GIT_DIR}/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd ${GIT_WORK_TREE}; git diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached [email protected]{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git update-ref --no-deref HEAD [email protected]{1}
cd ${GIT_WORK_TREE}
git stash save "dirty $desc before update to $new";
git symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd ${GIT_WORK_TREE}
git diff-index -R --name-status HEAD >&2
git reset --hard HEAD
# need to touch some files or restart the application? do that here:
# touch *.wsgi
)
}
if [ x"${is_bare}" = x"false" ]
then
active_branch=$(git symbolic-ref HEAD)
export GIT_DIR=$(cd ${GIT_DIR}; pwd)
GIT_WORK_TREE="${GIT_DIR}/.."
for ref in $(cat)
do
if [ x"$ref" = x"${active_branch}" ]
then
update_wc $ref
fi
done
fi

Honza
Einfaches Skript zum Einstellen dieser Git-Bereitstellung:
Post-Receive-Hook vorbereiten:
echo '#!/bin/sh' > .git/hooks/post-receive
echo 'git checkout -f' >> .git/hooks/post-receive
echo 'git reset --hard' >> .git/hooks/post-receive
chmod +x .git/hooks/post-receive
Push in dieses Repository zulassen, obwohl es nicht leer ist:
git config receive.denycurrentbranch false

nimmthin
Ich vermute nur, aber das könnte ein Berechtigungsproblem sein (vollständiger Pfad erforderlich? cd
?). Überprüfen Sie in den Protokolldateien, was wirklich passiert.
Das Veröffentlichen der Dateien über Git ist jedoch immer nur eine Aufgabe des Veröffentlichungsprozesses. Normalerweise müssen Sie einige Dateien kopieren, andere löschen, einrichten, Berechtigungen aktualisieren, Dokumente generieren usw.
Für eine komplexe Lösung ist ein Build-Skript möglicherweise besser als jeder Git-Hook. Tools, die diese Aufgaben sehr gut bewältigen können:
(Mir ist klar, dass dies nicht die Antwort ist, die Sie erwarten, aber es ist zu lang, um es als Kommentar zu posten.)
9643100cookie-checkGit Post-Receive-Hook für Website-Stagingyes
@VonC: Der wichtigste Teil Ihrer Antwort wurde größtenteils geschrieben
bash
Sprache, während der Downvoter wahrscheinlich seine Muttersprache behauptete;)– nimmthin
1. Oktober 2010 um 13:15 Uhr