¿Cómo puedo get git push para pedir confirmación o ejecutar algunos controles?

Me gustaría personalizar mi prompt de Git de tal manera que me recuerde o ejecute comprobaciones antes de enviar algo a un repository remoto.

Por ejemplo, cuando corro

git push 

Git debería preguntarle al usuario

 Did you run unit tests locally? 

o algo por el estilo, para no presionar accidentalmente el código que no está probado por la unidad.

Configure su gancho pre-push para evitar empujar a less que exista el file .testspassed . Ejemplo:

 cat > .git/hooks/pre-push <<EOF #!/bin/sh -e if ! [ -f .testspassed ]; then echo 1>&2 "push aborted because tests were not run or did not all pass" exit 1 fi exit 0 EOF chmod +x .git/hooks/pre-push 

Configure su gancho prepare-commit-msg para eliminar .testspassed si existe:

 cat > .git/hooks/prepare-commit-msg <<EOF #!/bin/sh -e rm -f .testspassed exit 0 EOF 

Estoy usando prepare-commit-msg lugar de pre-commit porque prepare-commit-msg ejecuta en las fusiones. Cada vez que se compromete o se fusiona, git eliminará el file .testspassed , lo que le impedirá presionar.

Dile a git que ignore el file .testspassed para que no termine en tu repository:

 echo .testspassed >> .gitignore git commit -m 'add .testspassed to .gitignore' .gitignore 

Finalmente, modifique su process de testing para crear ("tocar"). Se .testspassed si todas las testings pasan. Cómo lo hace depende de cómo ejecuta sus testings.

Primero: Esto no funcionará (no en un sentido técnico, sino en un sentido de hábito humano). Ver la idea de Rob Mayoff en su lugar.

Sin embargo, para demostrar una implementación, puede poner lo siguiente en su ~/.bashrc :

 git() { if [[ $1 = push ]]; then printf %s "Did you run unit tests locally?" read response case $response in y|Y|yes|YES) command git "$@" ;; *) echo "Aborting" ;; esac else command git "$@" fi } 

Mejor, para implementar la idea de Rob:

 git() { local -a options=( ) while (( $# )) && [[ $1 = -* ]]; do case $1 in -C|-c) options+=( "$1" "$2" ); shift; shift ;; *) options+=( "$1" ); shift ;; esac done local base_dir=$(git rev-parse --show-toplevel) case $1 in commit|merge|rebase) touch "$base_dir/.untested" command git "${options[@]}" "$@" ;; push) if [[ -e "$base_dir/.untested" ]]; then echo "Untested commits exist; you must run tests" else command git "${options[@]}" "$@" fi ;; *) command git "${options[@]}" "$@" ;; esac } unittest() ( cd "$(git rev-parse --show-toplevel)" make test && rm .untested )