¿Cómo hilar el compromiso, en lugar del directory de trabajo?

Tengo un problema molesto Estamos ejecutando lanzando como un gancho precompromiso. El problema es que está borrando el directory de trabajo en lugar de la confirmación real. Hay dos problemas con esto:

  1. Commit es malo, pero pases deshilachados.
    Si olvida realizar los cambios después de solucionar los problemas de deshilachado, esto es lo que sucede.

  2. Comprometerse es bueno, pero la falla falla.
    A menudo tengo algún código de debugging que no pretendo comprometer. Realmente no tiene sentido perder esos cambios y es molesto tratar con ellos.

Ahora, la pregunta es cómo puedo escribir un gancho de precompilation más inteligente que borre la confirmación real en lugar del directory de trabajo, preferiblemente sin cambiar el directory de trabajo.

Esto es en general bastante difícil.

El método más directo es extraer el índice en un directory temporal. Esto tiene algunos inconvenientes obvios: en particular, los files ignorados que viven en el tree de trabajo no se cargan en el directory temporal. Peor aún, el directory temporal solo tiene los files de este repository: cualquier entorno (submodules y / o superproyectos, por ejemplo) no se transfiere.

Llevar estas cosas a cabo es posible, pero consume, potencialmente, mucho espacio y / o time.

Aquí hay un método simple para llevar todo el tree de trabajo (incluidos los submodules) a un directory temporal, y luego extraer el contenido del índice sobre él:

 #! /bin/sh -e tmpdir=$(mktemp -d) trap "rm -rf $tmpdir" 0 1 2 3 15 # remainder assumes we are at top of work-tree, which is true in # practice in git hooks, even if it is not documented anywhere. # step 1: copy current tree to tmp dir tar cf - . | (cd $tmpdir; tar xf -) # step 2: extract current index to tmp dir git --work-tree=$tmpdir checkout -- . # step 3: run tests ... tests go here ... 

Para anzuelos precomprometidos que deseen modificar files (por ejemplo, usar gofmt o clang-format ), esto gofmt con la idea general, ya que ahora los files modificados se encuentran en un directory temporal que se elimina.