FreeToGenerate.com

Todos los hooks, ejecutados en vez de copiados del manual.

Consulta un hook

se ejecuta donde trabajas

La documentación dice
no puede cambiar el resultado, pero su estado de salida pasa a ser el del comando
Lo que pasó de verdad
la operación se completó y aun así el comando falló
Operación ejecutada
git checkout
Código de salida
1

Da igual las mayúsculas. Prueba post-checkout, pre-rebase o reference-transaction: cada uno desmiente una suposición distinta.

Medido, no copiado

hooks documentados
28
ejecutados de verdad
19
detuvieron la operación
11
no cambiaron nada
7
hicieron fallar el comando igualmente
1

Cada hook se instaló solo, con un cuerpo que no hacía más que fallar, en un repositorio desechable con un remoto bare local. Cada caso se ejecutó también sin ningún hook, y ese control tenía que salir bien antes de dar por válida la medición.

El nombre no es la regla. Solo 6 de los 11 hooks que detuvieron algo se llaman pre-algo; applypatch-msg, commit-msg, prepare-commit-msg, update y reference-transaction también detienen cosas.

git version 2.54.0.windows.1

Los 28 hooks

28 visibles
HookDónde se ejecutaDocumentadoMedido
applypatch-msgse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
pre-applypatchse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
post-applypatchse ejecuta donde trabajassu estado de salida se ignorano cambió absolutamente nada
pre-commitse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
pre-merge-commitse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
prepare-commit-msgse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
commit-msgse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
post-commitse ejecuta donde trabajassu estado de salida se ignorano cambió absolutamente nada
pre-rebasese ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
post-checkoutse ejecuta donde trabajasno puede cambiar el resultado, pero su estado de salida pasa a ser el del comandola operación se completó y aun así el comando falló
post-mergese ejecuta donde trabajassu estado de salida se ignorano cambió absolutamente nada
pre-pushse ejecuta donde trabajassalir con estado distinto de cero aborta la operaciónla operación se detuvo
pre-receivese ejecuta en el extremo que recibe el pushsalir con estado distinto de cero aborta la operaciónla operación se detuvo
updatese ejecuta en el extremo que recibe el pushsalir con estado distinto de cero aborta la operaciónla operación se detuvo
proc-receivese ejecuta en el extremo que recibe el pushsu estado de salida solo cuenta en algunos estados
post-receivese ejecuta en el extremo que recibe el pushsu estado de salida se ignorano cambió absolutamente nada
post-updatese ejecuta en el extremo que recibe el pushsu estado de salida se ignorano cambió absolutamente nada
reference-transactionse ejecuta donde trabajassu estado de salida solo cuenta en algunos estadosla operación se detuvo
push-to-checkoutse ejecuta en el extremo que recibe el pushsalir con estado distinto de cero aborta la operación
pre-auto-gcse ejecuta donde trabajassalir con estado distinto de cero aborta la operación
post-rewritese ejecuta donde trabajassu estado de salida se ignorano cambió absolutamente nada
sendemail-validatese ejecuta donde trabajassalir con estado distinto de cero aborta la operación
fsmonitor-watchmanse ejecuta donde trabajassu estado de salida solo cuenta en algunos estados
p4-changelistse ejecuta dentro de git-p4salir con estado distinto de cero aborta la operación
p4-prepare-changelistse ejecuta dentro de git-p4salir con estado distinto de cero aborta la operación
p4-post-changelistse ejecuta dentro de git-p4su estado de salida se ignora
p4-pre-submitse ejecuta dentro de git-p4salir con estado distinto de cero aborta la operación
post-index-changese ejecuta donde trabajassu estado de salida se ignorano cambió absolutamente nada

La lista y la columna documentada salen de githooks(5), tal como viene con git. La columna medida sale de ejecutar cada hook.

También disponible en: English · Português · Français · العربية

Git hooks: la lista completa y cuáles pueden pararte

El conjunto completo que documenta git, y la respuesta medida a lo único que importa: ¿puede este hook detener lo que estás haciendo?

¿Qué es un hook de git?

Un hook de git es un archivo ejecutable dentro del directorio de hooks de tu repositorio, con el nombre de un momento de la vida de git. Cuando llega ese momento —vas a hacer un commit, acabas de fusionar, un push ha llegado al servidor— git ejecuta el archivo. Así impone un proyecto un formato de mensaje de commit, pasa un linter antes de que el código entre o rechaza un push forzado a la rama principal.

Git documenta 28. La mayoría de la gente se cruza con tres o cuatro. El resto cubre la aplicación de parches por correo, el rebase, el extremo receptor de un push, la recolección de basura y un puente a Perforce, y varios se ejecutan en sitios que jamás adivinarías por el nombre.

La pregunta con la que llega cualquiera es simple: si este hook falla, ¿me para? Todas las referencias que hemos encontrado responden copiando la lista del manual de git. Esta página responde ejecutándolos.

Cómo usarla

  1. Escribe el nombre de un hook. Obtienes dónde se ejecuta, qué dice la documentación de git sobre su estado de salida y qué pasó cuando se instaló de verdad y se le hizo fallar.
  2. O busca en todo el conjunto. La tabla de abajo tiene los 28. Buscar un comando de git —commit, push, git am— devuelve todos los hooks que se disparan durante él.
  3. Lee las dos columnas una contra otra. Vienen de sitios distintos, así que donde coinciden puedes fiarte de la respuesta, y donde la documentación no tiene palabra para lo que ocurre, la medición aporta una.

Qué pasó al ejecutarlos

Cada hook se instaló por su cuenta, en un repositorio desechable con un remoto bare local al lado, con un cuerpo que no hacía más que fallar. Después se realizó la operación a la que ese hook pertenece y se anotaron dos cosas: el código de salida que devolvió el comando y si el estado del repositorio se movió de verdad. Diecinueve de los 28 se pueden disparar así; el resto necesitan un depósito de Perforce, un transporte de correo, watchman o el protocolo de push más nuevo, y se dejan en blanco en vez de adivinarlos.

Cada caso se ejecutó además sin ningún hook instalado, y ese control tenía que salir bien y mover el estado antes de que la medición contara para nada. No es ceremonia. La primera versión de este experimento informó de que el hook pre-rebase no puede detener un rebase, lo cual es falso y pasó porque la rama que construía no tenía nada que rebasear, así que la operación no hacía nada hubiera hook o no. El control convirtió una falsedad publicable y plausible en un fallo ruidoso.

De los diecinueve: once detuvieron la operación, siete no cambiaron absolutamente nada y uno hizo algo para lo que no hay palabra corriente.

El hook que falla sin fallar

El hook post-checkout no puede detener un checkout. La propia documentación de git dice que no puede afectar al resultado, salvo en que el estado de salida del hook pasa a ser el estado de salida del comando. Medido, es exactamente lo que ocurre: el checkout se completa, estás en la rama nueva y git devuelve 1.

Así que un script escrito como un checkout seguido de un comando encadenado, que es como se escriben casi todos los scripts de despliegue y los pasos de CI, se para en seco en un repositorio cuyo hook post-checkout falla. El checkout funcionó. El comando falló. Son hechos distintos y solo uno de los dos es visible para el shell.

Merece la pena conocer otro código de salida. Cuando el hook reference-transaction rechaza en su estado prepared, git no devuelve un fallo normal: devuelve 128, su código para un error fatal. Cualquier cosa que compare códigos de salida debería esperarlo en vez de un 1.

El nombre no es la regla

Todo el mundo lo aprende así: los hooks que empiezan por pre- pueden bloquear, los que empiezan por post- no. La mitad es cierta. Nada llamado post- detuvo nada, y todos los hooks que no cambiaron absolutamente nada se llamaban post-algo.

La otra mitad falla. Solo 6 de los 11 hooks que detuvieron una operación se llaman pre-algo. Los otros cinco son applypatch-msg, commit-msg, prepare-commit-msg, update y reference-transaction, así que casi la mitad de lo que puede pararte no lo avisa en su nombre. prepare-commit-msg es la trampa dentro de la trampa: empieza por las letras p-r-e, no es un hook pre- y bloquea.

La regla de verdad es si git consulta el estado de salida en el punto donde se ejecuta el hook, que es una propiedad de la operación y no del nombre. Por eso update detiene un push, por eso reference-transaction puede impedir que se cree una rama y por eso post-checkout puede hacer fallar un comando sin cambiar nada.

Lo que esta página no puede decirte

Es una versión de git en una plataforma. La medición se tomó con la versión de git que aparece junto a las cifras, en Windows, y aunque la semántica de los hooks cambia despacio, cambia. Donde la documentación y la medición coinciden —que es en todo lo que se solapan— la respuesta es tan sólida como se puede sin leer el código fuente.

Nueve hooks no se midieron, y así lo dice su fila en vez de rellenarla. Uno de ellos, pre-auto-gc, se intentó y se abandonó: la recolección automática de basura solo se ejecuta cuando git decide que un repositorio tiene bastantes objetos sueltos, y esa decisión muestrea un directorio en vez de contar, así que ningún repositorio de prueba lo bastante pequeño la disparaba. Una fila cuyo control no puede hacerse honesto se deja fuera.

Por último, esto va de si un hook puede detener una operación, no de si debería. Un hook que rechaza trabajo solo sirve si la persona a la que para puede saber por qué, y git no imprime nada en tu nombre: lo que tu hook escriba en la salida de error es el mensaje entero que verá cualquiera.

¿Por qué es gratis?

La lista entera son un par de kilobytes que viajan con la página y se buscan en tu navegador. Nada de lo que escribes se sube, no se registra nada y no hay cuenta que crear.

Sin registro, sin límites y sin marca de agua en nada de lo que copies.