¿Cómo actualizar automáticamente los ganchos de git?

Entonces, el único gancho que uso es el post-recibo. Cuando edito este file en mi cliente, quiero que se actualice automáticamente cuando presiono al server.

Intenté 3 cosas que no funcionaron. En los ganchos post-recepción I

  1. simbólicamente vinculado al file en el repository
  2. fuertemente vinculado al file en el repository
  3. finalmente, copió el file del repository en el directory de ganchos.

Por lo tanto, conservo una copy de este file en mi repository, pero quiero que se implemente automáticamente.

Creo que el problema principal con los methods que bash es que el file se esté utilizando cuando bash actualizarlo, es decir, que actúa sobre sí mismo.

¿Hay una manera defacto de hacer esto?

Una posibilidad sería que su gancho post-receive :

  • detectar que el script post-receive es parte de lo que se empuja.
    (Consulte " git post-receive hook para verificar files ": git diff --name-only $1..$2|grep post-receive )
  • hacer una copy en .git/hook/post-receive.new

A continuación, instale un gancho de pre-receive que simplemente compruebe .git/hook/post-receive.new y cambie el nombre como .git/hook/post-receive .
(El significado post-receive.new desaparece, y la próxima ejecución de gancho pre-receive no hará nada)

De esta forma, el gancho no se actualiza de inmediato , pero se actualizará en el próximo git push a ese mismo repository.


Nota: Pensé en detectar y actualizar la modificación del file post-receive directamente durante la ejecución del enlace pre-receive , pero, como explica torek en " Git pre-receive hook para verificar la configuration ", esto no es trivial:

Se llama a un gancho de pre-receive o update después de que los nuevos objects (confirmaciones, objects de label anotados, treees y blobs) se hayan cargado en el repository, pero antes de que se hayan cambiado las references (nombres de twig, nombres de label, etc.).

Necesitaría, por cada reference que se presione, diferir y verificar la presencia y el contenido de ese file.
No es imposible, como se ve en este script php :

 function get_changed_files($base, $commit) { list($code, $stdout, $stderr) = git('diff', '--numstat', '--name-only', '--diff-filter=ACMRTUXB', '--ignore-submodules', "{$base}..{$commit}"); ... return explode("\n", $stdout); } function get_new_file($filename, $commit) { list($code, $stdout, $stderr) = git('show', "{$commit}:{$filename}"); ... return $stdout; } ... $line = file_get_contents('php://stdin'); list($base, $commit, $ref) = explode(" ", trim($line)); if ($base == "0000000000000000000000000000000000000000") { verbose("Initial push received. Expecting everything to be fine"); exit; } $modified = get_changed_files($base, $commit); $result = true; foreach ($modified as $fname) { // if fname equals post-receive $contents = get_new_file($fname, $commit); // copy it to .git/hooks/post-receive } 

Tener un process de dos pasos es más fácil.