receive ocean made hooks example easy digitalocean create automate git git-post-receive

ocean - Git Post-Receive Hook para la puesta en escena del sitio web



git local hooks (6)

Actualización de marzo de 2015

Como mencioné en " ¿Qué es este mensaje de advertencia de Git cuando empujo los cambios a un repositorio remoto? ", En realidad puede pasar directamente a un repositorio no desnudo ahora (Git 2.3.0+, febrero de 2015) con:

git config receive.denyCurrentBranch updateInstead

Actualice el árbol de trabajo en consecuencia, pero se niega a hacerlo si hay cambios no confirmados.

Eso le permitiría evitar cualquier gancho posterior a la recepción.

(Respuesta original: oct 2010)

El GitFAQ recomienda para repo non-bare este gancho post-actualización:
(Podría darle más pistas sobre lo que está sucediendo realmente en la ejecución del enlace. Tenga en cuenta que este es un enlace posterior a la actualización, no un mensaje posterior a la recepción).

#!/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 HEAD@{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 HEAD@{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

Para que esto funcione, aún debe permitir específicamente realizar cambios en la bifurcación actual utilizando cualquiera de estas configuraciones:

git config receive.denyCurrentBranch ignore

o

git config receive.denyCurrentBranch warn

Intento configurar Git para organizar mi sitio web para que pueda hacer git pull para que la versión actual funcione localmente y luego git push para enviar los cambios al servidor remoto. Lo tengo configurado para que funcione como yo quiero, pero después de presionar, tengo que ejecutar manualmente git checkout -f o git reset --hard HEAD en el servidor remoto.

Intenté poner estos en un script de shell como el gancho de post-recepción en el servidor, pero simplemente no parece tener ningún efecto. Sé que el script se está ejecutando porque veo "Cambios empujados al servidor" después de presionar. Aquí está el gancho post-recepción:

#!/bin/sh git reset --hard HEAD echo "Changes pushed to server."


La respuesta a su pregunta está aquí: http://toroid.org/ams/git-website-howto

En resumen, lo que quiere hacer es agregar un "árbol de trabajo separado" al repositorio desnudo. Normalmente piensas que tu árbol de trabajo contiene el directorio .git . Los repositorios desnudos no tienen un árbol de trabajo por definición, pero puede crear uno siempre que esté en un directorio diferente al repositorio simple.

El gancho posterior a la recepción es simplemente una simple git checkout -f para replicar HEAD del repositorio en el directorio de trabajo. Apache lo utiliza como su raíz de documento, y ya está todo listo. Cada vez que ingresas al repositorio simple, Apache inmediatamente comenzará a servirlo.

Generalmente uso esto para enviar automáticamente a un servidor intermedio para ver si el entorno "real" vomitará en mis cambios. Desplegar al servidor en vivo es una historia completamente diferente. :-)


La versión fija del script de VonC, funciona para mí (absolutamente no hay garantías).

#!/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 HEAD@{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 HEAD@{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


Solo estoy adivinando, pero esto puede ser un problema de permiso (¿se necesita una ruta completa? ¿ cd ?). Compruebe lo que realmente está sucediendo en los archivos de registro.

Sin embargo, publicar los archivos a través de git siempre es solo una tarea del proceso de publicación. Por lo general, necesita copiar algunos archivos, eliminar otros, configurar, actualizar permisos, generar documentos, etc.

Para una solución compleja, un script de construcción podría ser mejor que cualquier git hook. Herramientas que pueden manejar esas tareas muy bien:

(Me doy cuenta de que esta no es la respuesta que estás esperando, pero es demasiado larga para publicarla como comentario)


Yo tuve exactamente el mismo problema. En una respuesta a este enlace: http://toroid.org/ams/git-website-howto - El siguiente comando lo ha hecho:

sudo chmod +x hooks/post-receive

Perdimos un permiso de sudo primero configurado las cosas.


Script simple para configurar esta implementación de git:

Preparación del enlace posterior a la recepción:

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

Permitir la inserción en este repositorio, aunque no es simple:

git config receive.denycurrentbranch false