Git pre-commit hook: archivos cambiados / añadidos


Estoy escribiendo un gancho pre-commit. Quiero ejecutar php -l contra todos los archivos con .extensión php. Sin embargo estoy atascado.

Necesito obtener una lista de los archivos nuevos/modificados que están preparados. los archivos eliminados deben ser excluidos.

He intentado usar git diff y git ls-files, pero creo que necesito una mano aquí.

Author: igorw, 2010-03-09

5 answers

git diff --cached --name-status mostrará un resumen de lo que está preparado, para que pueda excluir fácilmente los archivos eliminados, por ejemplo:

M       wt-status.c
D       wt-status.h

Esto indica que wt-status.c fue modificado y estado wt.h se eliminó en el área de estadificación (índice). Por lo tanto, para comprobar solo los archivos que no se eliminaron:

steve@arise:~/src/git <master>$ git diff --cached --name-status | awk '$1 != "D" { print $2 }'
wt-status.c
wt-status.h

Tendrás que saltar a través de aros adicionales para lidiar con nombres de archivo con espacios en (opción-z para git diff y un análisis más interesante)

 42
Author: araqnid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-13 00:31:46

Una forma un poco más ordenada de obtener la misma lista es:

git diff --cached --name-only --diff-filter=ACM

Esto devolverá la lista de archivos que necesitan ser comprobados.

Pero simplemente ejecutar php -l en su copia de trabajo puede no ser lo correcto. Si está haciendo un commit parcial, es decir, simplemente seleccionando un subconjunto de las diferencias entre su conjunto de trabajo actual y la CABEZA para el commit, entonces la prueba se ejecutará en su conjunto de trabajo, pero certificará un commit que nunca ha existido en su disco.

Para hacerlo bien, debe extraer toda la imagen por etapas a un área temporal y realizar la prueba allí .

rm -rf $TEMPDIR
mkdir -p $TEMPDIR
git checkout-index --prefix=$TEMPDIR/ -af
git diff --cached --name-only --diff-filter=ACM | xargs -n 1 -I '{}' \bin\echo TEMPDIR/'{}' | grep \\.php | xargs -n 1 php -l

Ver Construir un mejor gancho pre-commit para Git para otra implementación.

 76
Author: LarryH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-22 14:44:23

Esto es lo que uso para mis comprobaciones de Perl:

git diff --cached --name-status | while read st file; do
        # skip deleted files
        if [ "$st" == 'D' ]; then continue; fi
        # do a check only on the perl files
        if [[ "$file" =~ "(.pm|.pl)$" ]] && ! perl -c "$file"; then
                echo "Perl syntax check failed for file: $file"
                exit 1
        fi
done

Para PHP se verá así:

git diff --cached --name-status | while read st file; do
        # skip deleted files
        if [ "$st" == 'D' ]; then continue; fi
        # do a check only on the php files
        if [[ "$file" =~ ".php$" ]] && ! php -l "$file"; then
                echo "PHP syntax check failed for file: $file"
                exit 1
        fi
done
 7
Author: Marian HackMan Marinov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-05 23:45:06

Ninguna de las respuestas aquí admite nombres de archivo con espacios. La mejor manera de hacerlo es agregar la bandera -z en combinación con xargs -0

git diff --cached --name-only --diff-filter=ACM -z | xargs -0 ...

Esto es lo que da git en las muestras integradas (ver .git / hooks / pre-commit.muestra )

 7
Author: eddygeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-20 13:05:15

Git diff c cached no es suficiente si la llamada de confirmación se especificó con el indicador-a, y no hay forma de determinar si ese indicador se ha lanzado en el gancho. Sería útil que los argumentos a confirmar estuvieran disponibles para el hook para su examen.

 1
Author: mpersico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-10 17:16:44