ver modificados log ignorar comandos cambios archivos archivo and git shell

modificados - Buscando un índice sucio o archivos sin seguimiento con Git



ignorar cambios git (12)

¿Cómo puedo verificar si tengo cambios no confirmados en mi repositorio de git?

  1. Cambios añadidos al índice pero no confirmados.
  2. Archivos sin seguimiento

de un guión?

git-status parece devolver siempre cero con git versión 1.6.4.2.


¡Gran momento! Escribí una publicación en el blog sobre esto exactamente hace unos días, cuando descubrí cómo agregar información de estado de git a mi indicador.

Esto es lo que hago:

  1. Para estado sucio:

    # Returns "*" if the current git branch is dirty. function evil_git_dirty { [[ $(git diff --shortstat 2> /dev/null | tail -n1) != "" ]] && echo "*" }

  2. Para archivos no --porcelain ( --porcelain indicador --porcelain para obtener el git status --porcelain que le brinda una salida agradable y fácil de --porcelain ):

    # Returns the number of untracked files function evil_git_num_untracked_files { expr `git status --porcelain 2>/dev/null| grep "^??" | wc -l` }

Aunque git diff --shortstat es más conveniente, también puede usar git status --porcelain para obtener archivos sucios:

# Get number of files added to the index (but uncommitted) expr $(git status --porcelain 2>/dev/null| grep "^M" | wc -l) # Get number of files that are uncommitted and not added expr $(git status --porcelain 2>/dev/null| grep "^ M" | wc -l) # Get number of total uncommited files expr $(git status --porcelain 2>/dev/null| egrep "^(M| M)" | wc -l)

Nota: 2>/dev/null filtra los mensajes de error para que pueda usar estos comandos en directorios que no sean git. (Simplemente devolverán 0 para los recuentos de archivos).

Editar :

Aquí están los mensajes:

Agregar información de estado de Git a su solicitud de terminal

Indicador de shell habilitado para Git mejorado


¿Por qué no encapsular el git status con un script que:

  • analizará la salida de ese comando
  • Devolverá el código de error apropiado en función de lo que necesite

De esa manera, puedes usar ese estado ''mejorado'' en tu script.

Como menciona en su excelente respuesta , git status --porcelain es fundamental en cualquier solución basada en script

--porcelain

Proporcione la salida en un formato estable y fácil de analizar para los scripts.
Actualmente esto es idéntico a --short output , pero se garantiza que no cambiará en el futuro, lo que lo hace seguro para los scripts.


Aquí está la manera mejor, más limpia. La respuesta seleccionada no me funcionó por alguna razón, no recogió los cambios en etapas que eran archivos nuevos que no se habían confirmado.

function git_dirty { text=$(git status) changed_text="Changes to be committed" untracked_files="Untracked files" dirty=false if [[ ${text} = *"$changed_text"* ]];then dirty=true fi if [[ ${text} = *"$untracked_files"* ]];then dirty=true fi echo $dirty }


Eché un vistazo a algunas de estas respuestas ... (y tuve varios problemas en * nix y windows, que era un requisito que tenía) ... encontré que lo siguiente funcionó bien ...

git diff --no-ext-diff --quiet --exit-code

Para comprobar el código de salida en * nix

echo $? #returns 1 if the repo has changes (0 if clean)

Para comprobar el código de salida en la ventana $

echo %errorlevel% #returns 1 if the repos has changes (0 if clean)

Obtenido de https://github.com/sindresorhus/pure/issues/115 Gracias a @paulirish en esa publicación por compartir


Esta es una variante más sencilla para descubrir si existe algún archivo sin seguimiento en el repositorio:

# Works in bash and zsh if [[ "$(git status --porcelain 2>/dev/null)" = */?/?* ]]; then echo untracked files fi

Esto no conlleva un segundo proceso, grep , y no es necesario verificar si está en un repositorio de git o no. Lo que es útil para las instrucciones de shell, etc.


La clave para hacer un "script" de forma confiable a Git es usar los comandos de "fontanería".

Los desarrolladores se cuidan cuando cambian los comandos de plomería para asegurarse de que proporcionan interfaces muy estables (es decir, una combinación dada de estado de repositorio, stdin, opciones de línea de comando, argumentos, etc. producirán la misma salida en todas las versiones de Git donde el comando / existe la opción). Se pueden introducir nuevas variaciones de salida en los comandos de plomería a través de nuevas opciones, pero eso no puede introducir ningún problema para los programas que ya se han escrito en versiones anteriores (no usarían las nuevas opciones, ya que no existían (o al menos eran no utilizado) en el momento en que se escribió el script).

Desafortunadamente, los comandos ''cotidianos'' de Git son comandos ''de porcelana'', por lo que la mayoría de los usuarios de Git pueden no estar familiarizados con los comandos de plomería. La distinción entre comando de porcelana y plomería se realiza en la página principal de git (consulte las subsecciones tituladas Comandos de alto nivel (porcelana) y Comandos de bajo nivel (plomería) .

Para conocer los cambios no generados, es probable que necesites git diff-index (comparar índice (y quizás bits del árbol de trabajo rastreados) contra algún otro árbol (por ejemplo, HEAD )), tal vez git diff-files (comparar árbol de trabajo contra índice), y posiblemente git ls-files ( git ls-files lista; por ejemplo, lista de archivos sin seguimiento, sin identificar).

(Tenga en cuenta que en los siguientes comandos, HEAD -- se usa en lugar de HEAD porque de lo contrario el comando fails si hay un archivo llamado HEAD .)

Para verificar si un repositorio ha efectuado cambios (aún no confirmados) use esto:

git diff-index --quiet --cached HEAD --

  • Si sale con 0 entonces no hubo diferencias ( 1 significa que hubo diferencias).

Para verificar si un árbol de trabajo tiene cambios que podrían ser organizados:

git diff-files --quiet

  • El código de salida es el mismo que para git diff-index ( 0 == sin diferencias; 1 == diferencias).

Para verificar si la combinación del índice y los archivos rastreados en el árbol de trabajo tienen cambios con respecto a HEAD :

git diff-index --quiet HEAD --

  • Esto es como una combinación de los dos anteriores. Una de las principales diferencias es que seguirá informando "sin diferencias" si tiene un cambio por etapas que ha "deshecho" en el árbol de trabajo (regresó a los contenidos que están en HEAD ). En esta misma situación, los dos comandos separados devolverían los informes de "diferencias presentes".

También mencionó archivos sin seguimiento. Puede significar "sin seguimiento y sin marcar", o puede significar simplemente "sin seguimiento" (incluidos los archivos ignorados). De cualquier manera, git ls-files es la herramienta para el trabajo:

Para "sin seguimiento" (incluirá archivos ignorados, si están presentes):

git ls-files --others

Para "sin seguimiento y sin marcar":

git ls-files --exclude-standard --others

Mi primer pensamiento es simplemente comprobar si estos comandos tienen salida:

test -z "$(git ls-files --others)"

  • Si sale con 0 entonces no hay archivos sin seguimiento. Si sale con 1 entonces hay archivos sin seguimiento.

Existe una pequeña posibilidad de que esto traduzca las salidas anormales de git ls-files en informes de "archivos sin seguimiento" (ambos resultados dan como resultado salidas no cero del comando anterior). Una versión un poco más robusta podría verse así:

u="$(git ls-files --others)" && test -z "$u"

  • La idea es la misma que la del comando anterior, pero permite que se propaguen errores inesperados de git ls-files . En este caso, una salida que no sea cero podría significar "hay archivos sin seguimiento" o podría significar un error. Si desea que los resultados de "error" se combinen con el resultado de "no hay archivos sin seguimiento", use test -n "$u" (donde salir de 0 significa "algunos archivos sin seguimiento", y no cero significa error o "no hay archivos sin seguimiento ”).

Otra idea es utilizar --error-unmatch para provocar una salida distinta de cero cuando no hay archivos sin seguimiento. Esto también corre el riesgo de combinar "no hay archivos sin seguimiento" (salida 1 ) con "se produjo un error" (salida no cero, pero probablemente 128 ). Pero la comprobación de los códigos de salida 0 vs. 1 vs. no cero es probablemente bastante robusta:

git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$? if test "$ec" = 0; then echo some untracked files elif test "$ec" = 1; then echo no untracked files else echo error from ls-files fi

Cualquiera de los ejemplos anteriores de git ls-files puede tomar --exclude-standard si desea considerar solo archivos sin seguimiento y sin identificar.


La prueba automática más sencilla que utilizo para detectar el estado sucio = cualquier cambio, incluidos los archivos sin seguimiento :

git add --all git diff-index --exit-code HEAD

NOTA:

  • Sin add --all diff-index no notan archivos sin seguimiento.
  • Normalmente, ejecuto git reset después de probar el código de error para desestabilizar todo.

Puede haber una mejor combinación de respuestas de este hilo ... pero esto funciona para mí ... para la .gitconfig [alias] de su .gitconfig ...

# git untracked && echo "There are untracked files!" untracked = ! git status --porcelain 2>/dev/null | grep -q "^??" # git unclean && echo "There are uncommited changes!" unclean = ! ! git diff --quiet --ignore-submodules HEAD > /dev/null 2>&1 # git dirty && echo "There are uncommitted changes OR untracked files!" dirty = ! git untracked || git unclean


Tambien puedes hacer

git describe --dirty

. Agregará la palabra "-dirty" al final si detecta un árbol de trabajo sucio. Según git-describe(1) :

--dirty[=<mark>] Describe the working tree. It means describe HEAD and appends <mark> (-dirty by default) if the working tree is dirty.

. Advertencia: los archivos sin seguimiento no se consideran "sucios" porque, como se indica en la página del manual, solo se preocupa por el árbol de trabajo.


Una implementación de la VonC de VonC :

if [[ -n $(git status --porcelain) ]]; then echo "repo is dirty"; fi


Una posibilidad de bricolaje, actualizada para seguir la sugerencia de .

#!/bin/sh exit $(git status --porcelain | wc -l)

Como lo señaló , esto solo funciona en Git 1.7.0 o más reciente.


Asumiendo que estás en git 1.7.0 o posterior ...

Después de leer todas las respuestas en esta página y experimentar un poco, creo que el método que encuentra la combinación correcta de corrección y brevedad es:

test -n "$(git status --porcelain)"

Si bien git permite una gran cantidad de matices entre lo que se rastrea, ignorar, no rastrear pero no marcar, y así sucesivamente, creo que el caso de uso típico es la automatización de scripts de compilación, donde desea detener todo si su pago no está limpio.

En ese caso, tiene sentido simular lo que haría el programador: escribir el git status y mirar la salida. Pero no queremos confiar en que aparezcan palabras específicas, así que usamos el modo --porcelain introducido en 1.7.0; cuando está habilitado, un directorio limpio no genera resultados.

Luego usamos test -n para ver si hubo alguna salida o no.

Este comando devolverá 1 si el directorio de trabajo está limpio y 0 si hay cambios para confirmar. Puedes cambiar la -n a una -z si quieres lo contrario. Esto es útil para encadenar esto a un comando en un script. Por ejemplo:

test -z "$(git status --porcelain)" || red-alert "UNCLEAN UNCLEAN"

Esto dice de manera efectiva que "o no hay cambios que hacer o activar una alarma"; esta frase de una sola línea puede ser preferible a una sentencia if en función del script que esté escribiendo.