Respuestas:
Generalmente estoy de acuerdo con Scytale, con un par de sugerencias adicionales, lo suficiente como para que valga una respuesta por separado.
Primero, debe escribir una secuencia de comandos que cree los enlaces simbólicos apropiados, especialmente si estos enlaces son para hacer cumplir la política o crear notificaciones útiles. Es mucho más probable que las personas usen los ganchos si solo pueden escribir bin/create-hook-symlinks
que si tienen que hacerlo ellos mismos.
En segundo lugar, los enlaces directos simbólicos evitan que los usuarios agreguen sus propios enlaces personales. Por ejemplo, prefiero el gancho de precompromiso de muestra que garantiza que no tenga ningún error de espacio en blanco. Una excelente forma de evitar esto es colocar un script de contenedor de gancho en su repositorio y vincular todos los ganchos a él. Luego, el contenedor puede examinar $0
(suponiendo que es un script bash; un equivalente como lo argv[0]
contrario) para averiguar en qué gancho se invocó, y luego invocar el gancho apropiado dentro de su repositorio, así como el gancho del usuario apropiado, que tendrá que renombrarse , pasando todos los argumentos a cada uno. Ejemplo rápido de memoria:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
El script de instalación movería todos los ganchos preexistentes a un lado (agregar .local
sus nombres) y vincularía todos los nombres de gancho conocidos al script anterior:
#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
for hook in $HOOK_NAMES; do
# If the hook already exists, is executable, and is not a symlink
if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
fi
# create the symlink, overwriting the file if it exists
# probably the only way this would happen is if you're using an old version of git
# -- back when the sample hooks were not executable, instead of being named ____.sample
ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
.
No, ponerlos en el repositorio está bien, incluso sugeriría hacerlo (si también son útiles para otros). El usuario tiene que habilitarlos explícitamente (como dijiste, por ejemplo, mediante simblinking), lo que por un lado es un poco difícil, pero por otro lado protege a los usuarios de ejecutar código arbitrario sin su consentimiento.
Hoy en día puede hacer lo siguiente para establecer un directorio que esté bajo control de versiones para que sea su directorio git hooks, por ejemplo, MY_REPO_DIR/.githooks
sería
git config --local core.hooksPath .githooks/
Todavía no se puede hacer cumplir directamente, pero si agrega una nota en su archivo README (o lo que sea), esto requiere un mínimo esfuerzo por parte de cada desarrollador.
Desde http://git-scm.com/docs/git-init#_template_directory , puede usar uno de estos mecanismos para actualizar el directorio .git / hooks de cada repositorio de git recién creado:
El directorio de plantillas contiene archivos y directorios que se copiarán en $ GIT_DIR después de crearlo.
El directorio de la plantilla será uno de los siguientes (en orden):
el argumento dado con la opción --template;
el contenido de la variable de entorno $ GIT_TEMPLATE_DIR;
la variable de configuración init.templateDir; o
el directorio de plantillas predeterminado: / usr / share / git-core / templates.
Como otros dicen en su respuesta, si sus ganchos son específicos para sus proyectos particulares, inclúyalos en el proyecto mismo, administrado por git. Llevaría esto aún más lejos y diría que, dado que es una buena práctica tener la compilación de su proyecto utilizando un solo script o comando, sus ganchos deben instalarse durante la compilación.
Escribí un artículo sobre la gestión de git hooks , si está interesado en leer sobre esto con un poco más de profundidad.
Descargo de responsabilidad completo; Escribí el complemento Maven que se describe a continuación.
Si está manejando la gestión de compilación con Maven para sus proyectos Java, el siguiente complemento Maven maneja la instalación de enlaces desde una ubicación en su proyecto.
https://github.com/rudikershaw/git-build-hook
Coloque todos sus ganchos Git en un directorio en su proyecto, luego configúrelo pom.xml
para incluir la siguiente declaración, objetivo y configuración del complemento.
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<configuration>
<gitConfig>
<!-- The location of the directory you are using to store the Git hooks in your project. -->
<core.hooksPath>hooks-directory/</core.hooksPath>
</gitConfig>
</configuration>
<executions>
<execution>
<goals>
<!-- Sets git config specified under configuration > gitConfig. -->
<goal>configure</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
Cuando ejecuta su proyecto, el complemento configurará git para ejecutar enlaces fuera del directorio especificado. Esto configurará efectivamente los ganchos en ese directorio para todos los que trabajen en su proyecto.
Para NPM hay una dependencia llamada Husky que le permite instalar ganchos, incluidos los escritos en JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Además, hay pre-commit para proyectos de Python, Overcommit para proyectos de Ruby y Lefthook para proyectos de Ruby o Node.
El paquete https://www.npmjs.com/package/pre-commit npm maneja esto de manera elegante, permitiéndole especificar ganchos de precompromiso en su package.json.
Aquí hay un script, add-git-hook.sh, que puede enviar como un archivo normal en el repositorio y puede ejecutarse para agregar el gancho git al archivo de script. Ajuste qué gancho usar (pre-commit, post-commit, pre-push, etc.) y la definición del gancho en el cat heredoc.
#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
# Note: CWD must be inside target repository
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit
# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
echo '#!/usr/bin/bash' >> "$HOOK_FILE"
chmod 700 "$HOOK_FILE"
fi
# Append hook code into script
cat >> "$HOOK_FILE" <<EOF
########################################
# ... post-commit hook script here ... #
########################################
EOF
Este script puede tener sentido para tener permisos ejecutables o el usuario puede ejecutarlo directamente. Usé esto para git-pull automáticamente en otras máquinas después de que me comprometí.
EDITAR: respondí la pregunta más fácil que no era lo que se preguntó y no era lo que estaba buscando el OP. Opiné sobre los casos de uso y los argumentos para enviar scripts de gancho en el repositorio en lugar de administrarlos externamente en los comentarios a continuación. Espero que sea más lo que estás buscando.
Para proyectos PHP basados en Composer, puede distribuir automáticamente a los ingenieros. Aquí hay un ejemplo para los enlaces pre-commit y commit-msg.
Cree una hooks
carpeta, luego en su composer.json:
},
"scripts": {
"post-install-cmd": [
"cp -r 'hooks/' '.git/hooks/'",
"php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
"php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
"php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
"php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
],
Luego, incluso puede actualizarlos a medida que el proyecto continúa, ya que todos se ejecutan composer install
regularmente.
Puede usar una solución administrada para la administración de enlace de precompromiso como precompromiso . O una solución centralizada para git-hooks del lado del servidor como Datree.io . Tiene políticas integradas como:
No reemplazará todos sus ganchos, pero podría ayudar a sus desarrolladores con los más obvios sin la configuración infernal de instalar los ganchos en cada computadora / repositorio de desarrolladores.
Descargo de responsabilidad: soy uno de los fundadores de Datrees
chmod +x .git/hooks/*
a tubin/create-hook-symlinks
para trabajarlo.