La clave para "guionar" Git de manera confiable es usar los comandos de "plomería".
Los desarrolladores tienen cuidado al cambiar los comandos de plomería para asegurarse de que proporcionen interfaces muy estables (es decir, una combinación dada de estado del repositorio, stdin, opciones de línea de comandos, argumentos, etc.) producirá la misma salida en todas las versiones de Git donde el comando / opción existe). Se pueden introducir nuevas variaciones de salida en los comandos de plomería a través de nuevas opciones, pero eso no puede presentar ningún problema para los programas que ya se han escrito en versiones anteriores (no estarían usando las nuevas opciones, ya que no existían (o al menos eran no utilizado) en el momento en que se escribió el guión).
Desafortunadamente, los comandos de Git 'cotidianos' son los 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 (vea las subsecciones tituladas Comandos de alto nivel (porcelana) y comandos de bajo nivel (plomería) .
Para conocer los cambios no comprometidos, es probable que necesite git diff-index
(compare el índice (y tal vez los bits del árbol de trabajo rastreados) con algún otro árbol (por ejemplo HEAD
)), tal vez git diff-files
(compare el árbol de trabajo con el índice) y posiblemente git ls-files
(enumere los archivos; por ejemplo, lista sin seguimiento , archivos no ignorados).
(Tenga en cuenta que en los comandos a continuación, HEAD --
se usa en lugar de HEAD
porque, de lo contrario, el comando falla 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 organizarse:
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 diferencia importante es que aún informará "sin diferencias" si tiene un cambio por etapas que ha "deshecho" en el árbol de trabajo (regresado a los contenidos que están en
HEAD
). En esta misma situación, los dos comandos separados devolverían informes de "diferencias presentes".
También mencionaste archivos sin seguimiento. Puede significar "sin seguimiento y sin ignorar", 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 ignorar":
git ls-files --exclude-standard --others
Mi primer pensamiento es simplemente verificar 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 los git ls-files
informes "sin archivos no rastreados" (ambos dan como resultado salidas distintas de 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
git ls-files
que se propaguen errores inesperados . En este caso, una salida distinta de cero podría significar "hay archivos sin seguimiento" o podría significar que se produjo un error. Si desea que los resultados de "error" se combinen con el resultado de "sin archivos sin seguimiento", use test -n "$u"
(donde salir de 0
significa "algunos archivos sin seguimiento" y no cero significa error o "sin archivos sin seguimiento").
Otra idea es usar --error-unmatch
para provocar una salida distinta de cero cuando no hay archivos sin seguimiento. Esto también corre el riesgo de combinar "no archivos no rastreados" (salir 1
) con "se produjo un error" (salir no es cero, pero probablemente 128
). Pero verificar los códigos de salida 0
vs. 1
vs. no cero es probablemente bastante robusto:
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
git ls-files
Puede tomar cualquiera de los ejemplos anteriores --exclude-standard
si desea considerar solo los archivos no rastreados y no ignorados.