Tengo un script que se ejecuta rsynccon un directorio de trabajo de Git como destino. Quiero que el script tenga un comportamiento diferente dependiendo de si el directorio de trabajo está limpio (sin cambios para confirmar), o no. Por ejemplo, si la salida de git statuses la siguiente, quiero que salga el script:
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
Si el directorio no está limpio, me gustaría ejecutar algunos comandos más.
¿Cómo puedo verificar la salida como la anterior en un script de shell?
shell-script
git
brentwpeterson
fuente
fuente

git reset --hard origin/brancheso si eso es lo que está buscando ... como si intentara limpiar después de compilar algo, etc.Respuestas:
Analizar la salida de
git statuses una mala idea porque la salida está destinada a ser legible por humanos, no legible por máquina. No hay garantía de que la salida sea la misma en futuras versiones de Git o en entornos con configuraciones diferentes.El comentario de UVV está en el camino correcto, pero desafortunadamente el código de retorno de
git statusno cambia cuando hay cambios no confirmados. Sin embargo, proporciona la--porcelainopción, que hace que la salidagit status --porcelainse formatee en un formato fácil de analizar para los scripts, y se mantendrá estable en todas las versiones de Git e independientemente de la configuración del usuario.Podemos usar la salida vacía de
git status --porcelaincomo un indicador de que no hay cambios que confirmar:Si no nos interesan los archivos no rastreados en el directorio de trabajo, podemos usar la
--untracked-files=noopción para ignorarlos:Para hacer esto más robusto contra las condiciones que realmente causan
git statusfallas sin salidastdout, podemos refinar la verificación para:También vale la pena señalar que, aunque
git statusno proporciona un código de salida significativo cuando el directorio de trabajo no está limpio,git diffproporciona la--exit-codeopción, que hace que se comporte de manera similar a la utilidad diff , es decir, salir con el estado1cuando hubo diferencias y0cuando no se encontraron ninguno.Con esto, podemos verificar los cambios no organizados con:
y escenificó, pero no cometió cambios con:
Aunque
git diffpuede informar sobre archivos no rastreados en submódulos a través de argumentos apropiados--ignore-submodules, desafortunadamente parece que no hay forma de que informe sobre archivos no rastreados en el directorio de trabajo real. Si los archivos no rastreados en el directorio de trabajo son relevantes,git status --porcelaines probablemente la mejor opción.fuente
git status --porcelainsaldrá con el código 0 incluso si hay cambios no organizados para commit y archivos no rastreados.git stashharía algo (no genera un código de retorno útil). Tuve que agregar--ignore-submodulesya que degit statuslo contrario indicaría cambios en el submódulo quegit stashignora.if [ -zestaba haciendo. Esto-zsignifica que si la siguiente cadena está vacía, el if se evalúa comotrue. En otras palabras, si esto nogit status --porcelainda como resultado una cadena, el repositorio está limpio. Si no, enumera los archivos modificados / agregados / eliminados y ya no es una cadena vacía. Elifentonces evalúa afalse.Utilizar:
El código de retorno refleja el estado del directorio de trabajo (0 = limpio, 1 = sucio). Los archivos sin seguimiento se ignoran.
fuente
git update-index --refreshantesgit diff-index HEAD. Más información: stackoverflow.com/q/34807971/1407170git add .antes de emitirlo. Por lo general, es la forma de usarlo en un scriptset +eantes de la llamadagity agregandoset -enuevamente después de haber evaluado$?.Extensión menor a la excelente respuesta de André .
Esta es una forma de evaluar los resultados y también evitar un escollo si se encuentra en un script que emitió previamente set -e .
Los archivos sin seguimiento se ignoran.
fuente