El problema es la diferencia en cómo se comportan los comandos de Git en el entorno creado para las secuencias de comandos hook en comparación con su entorno normal.
En primer lugar, las secuencias de comandos de anzuelo se ejecutan con su directorio de trabajo actual establecido en el directorio de Git (es decir, el directorio .git/
de un depósito no desnudo). En segundo lugar, las secuencias de comandos de anzuelo se ejecutan con la variable de entorno GIT_DIR configurada y apuntando al repositorio de Git (nuevamente, el directorio .git/
de un repositorio no desnudo).
Normalmente, si intenta ejecutar git reset --hard
desde el directorio .git/
, morirá con el siguiente mensaje:
fatal: This operation must be run in a work tree
Pero cuando se establece GIT_DIR, comandos de Git asumir que el directorio actual es el directorio de trabajo. Dado que el directorio actual cuando se ejecuta el gancho es .git/
, su git reset --hard
realmente está "revisando" los archivos de árbol de trabajo directamente en .git/
en lugar de su directorio principal (es decir, ahora tiene una copia de su contenido versionado en su directorio .git/
).
Esperemos que ninguno de los contenidos versionados en su repositorio tenga nombres de rutas que coincidan con pathnames that Git uses in Git repositories themselves. Si coinciden, entonces su git reset --hard
habrá sobrescrito parte de la estructura interna de su repositorio y es probable que desee volver a clonarlo desde otro repositorio.Si está seguro de que ninguno de los contenidos conflictos con versiones con nombres de rutas internas de Git, entonces usted puede ser capaz de limpiarlo con esto:
# make a backup of your repository first!
(cd .git && GIT_DIR=$PWD git ls-files -cz | xargs -0 rm)
Esto sólo eliminan archivos actualmente rastreados (que dejará atrás los archivos que tienen desde que se eliminó, pero una vez se realizó un seguimiento en las confirmaciones de punta empujadas mientras el gancho roto estaba activo).
Una solución es cambiar el directorio de trabajo actual en el árbol de trabajo normal y desarmar GIT_DIR y GIT_WORK_TREE antes de llamar a los comandos de Git.
⋮
test "${PWD%/.git}" != "$PWD" && cd ..
unset GIT_DIR GIT_WORK_TREE
# you can now safely use Git commands
⋮
Otra solución es reiniciar explícitamente GIT_DIR, establecer GIT_WORK_TREE y chdir allí. El FAQ de Git “Why won't I see changes in the remote repo after "git push"?” recomienda un post-update script que hace justamente esto. La secuencia de comandos vinculada también es mucho más segura ya que crea un alijo si el índice o el árbol de trabajo está sucio antes de realizar el restablecimiento completo.
Realmente debe publicar su script de gancho cuando tenga problemas con él. –
Chris, mi script posterior a la recepción solo contiene esa única línea. no es necesario publicar – David