Tengo un script que se ejecuta rsync
con 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 status
es 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/branch
eso si eso es lo que está buscando ... como si intentara limpiar después de compilar algo, etc.Respuestas:
Analizar la salida de
git status
es 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 status
no cambia cuando hay cambios no confirmados. Sin embargo, proporciona la--porcelain
opción, que hace que la salidagit status --porcelain
se 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 --porcelain
como 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=no
opción para ignorarlos:Para hacer esto más robusto contra las condiciones que realmente causan
git status
fallas sin salidastdout
, podemos refinar la verificación para:También vale la pena señalar que, aunque
git status
no proporciona un código de salida significativo cuando el directorio de trabajo no está limpio,git diff
proporciona la--exit-code
opción, que hace que se comporte de manera similar a la utilidad diff , es decir, salir con el estado1
cuando hubo diferencias y0
cuando no se encontraron ninguno.Con esto, podemos verificar los cambios no organizados con:
y escenificó, pero no cometió cambios con:
Aunque
git diff
puede 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 --porcelain
es probablemente la mejor opción.fuente
git status --porcelain
saldrá con el código 0 incluso si hay cambios no organizados para commit y archivos no rastreados.git stash
haría algo (no genera un código de retorno útil). Tuve que agregar--ignore-submodules
ya que degit status
lo contrario indicaría cambios en el submódulo quegit stash
ignora.if [ -z
estaba haciendo. Esto-z
significa que si la siguiente cadena está vacía, el if se evalúa comotrue
. En otras palabras, si esto nogit status --porcelain
da como resultado una cadena, el repositorio está limpio. Si no, enumera los archivos modificados / agregados / eliminados y ya no es una cadena vacía. Elif
entonces 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 --refresh
antesgit 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 +e
antes de la llamadagit
y agregandoset -e
nuevamente 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