2012-06-20 19 views
9

Desde hace un tiempo uso la función __git_ps1 en el indicador PS1 de mi bash (con PS1='\w$(__git_ps1)'). Ahora quiero colorearlo dependiendo del estado de la rama .La forma más rápida de obtener el estado de git en bash

Escribí una función bash que comprueba si la rama actual está modificada, y colores rojos o blancos dependiendo del estado. El problema es que usa git status para verificar el estado (es la única forma que conozco), y eso es varios veces más lento que __git_ps1, que es suficiente para causar un retraso molesto cuando estoy usando el indicador (estoy en una netbook muy débil).

Entonces pregunto: ¿hay alguna manera más rápida de verificar el estado de la carpeta git actual? __git_ps1 es mucho más rápido que el análisis manual de git branch, así que estoy pensando en que podría haber alguna otra función oculta de git.

+0

Para aclarar por mí mismo: ¿Desea saber si la rama tiene archivos sin seguimiento? –

+0

@PetervanderLo hace sí. Cualquier cosa que sea reportada por 'git status'. – Malabarba

+0

Nota: Git 2.6+ (Q3 2015) debería mejorar esto. Ver [mi respuesta a continuación] (http://stackoverflow.com/a/32039972/6309) – VonC

Respuesta

6

No es completamente su respuesta, pero bash-completion tiene esto incorporado.

Si establece el bash ENV GIT_PS1_SHOWDIRTYSTATE en un valor no vacío, los cambios no escalonados (*) y en etapas (+) se mostrarán junto al nombre de la rama. Puede configurar este por repositorio con la variable bash.showDirtyState, que por defecto es verdadera una vez que GIT_PS1_SHOWDIRTYSTATE está habilitado.

También puede ver si algo está escondido, estableciendo GIT_PS1_SHOWSTASHSTATE en un valor no vacío. Si algo está oculto, entonces se mostrará un '$' al lado del nombre de la rama.

Si desea ver si hay archivos sin seguimiento, puede establecer GIT_PS1_SHOWUNTRACKEDFILES en un valor no vacío. Si hay archivos sin seguimiento, se mostrará un '%' junto al nombre de la sucursal.

No estoy seguro acerca de la velocidad de degradación cuando habilita esto sin embargo. Si usted quiere hacer la coloración:

archivos Staged:

if git rev-parse --quiet --verify HEAD >/dev/null; then 
git diff-index --cached --quiet HEAD -- || color for staged changes 
else 
    color unstaged changes 
fi 

archivos escondidos

git rev-parse --verify refs/stash >/dev/null 2>&1 && color for stashed files 

Los archivos sin seguimiento

if [ -n "$(git ls-files --others --exclude-standard)" ]; then 
    Color untrack files 
fi 

Los fragmentos anteriores provienen de la fiesta de finalización guión.

+1

Buena respuesta, pero el primer script no funciona para mí. Parece 'git rev-parse --quiet --verify HEAD>/dev/null' siempre devuelve' 0' sin importar el estado en etapas/sin escena. – Malabarba

+0

La única forma en que no funcionará para mí es cuando aún no tengo una rama. ¿Cuál es la salida de 'git rev-parse --verify HEAD' –

+0

Un número hexadecimal grande. Intenté jugar un poco con las ramas, pero siempre devuelve 0. Sin embargo, eso no es un gran problema, es la otra cosa que decidí seguir con las variables GIT_PS1. ¿Dónde te enteraste de ellos? – Malabarba

3

git diff --quiet devuelve 1 si hay cambios en el directorio de trabajo y git diff --quiet --cached hace lo mismo para el índice.

Puede utilizarlo para hacer:

git diff --quiet 
    || echo "There be changes!" 
0

estoy usando ksh y estoy teniendo el mismo problema. Para colmo, mis repositorios Git están montados en NFS, lo que hace que el tiempo de respuesta sea aún más lento.

para responder directamente a la pregunta acerca de la velocidad, trate de usar:

git ls-files -m 

parece ser significativamente más rápido que 'git estado -s', después de haber introducido un repositorio diferente.Una vez dentro de un repositorio, el almacenamiento en caché del sistema operativo y NFS parece acelerar drásticamente este comando. Este comando también parece ser muy rápido cuando está dentro de las hojas inferiores del árbol de directorio de trabajo git.

Espero que esto ayude.
- JJ -

3

Nota: Git 2.6+ (Q3 2015) debería acelerar ese estado __git_ps1:

Ver commit dd160d7, commit 6bfab99 (19 Jul 2015) SZEDER Gábor (szeder).
(Fusionado por Junio C Hamano -- gitster -- en commit 461c119 03 Ago 2015)

pronta

bash: indicador de estado más rápido sin seguimiento con los directorios sin seguimiento

Si el indicador de estado sin seguimiento está activado, __git_ps1() busca los archivos sin seguimiento mediante la ejecución 'git ls-files'.
Esto puede ser perceptiblemente lento en el caso de un directorio sin seguimiento que contenga muchos archivos, ya que enumera todos los archivos encontrados en el directorio no rastreado solo para ser redirigido al /dev/null de inmediato.
Este es el comando real dirigido por __git_ps1():

$ ls untracked-dir/ |wc -l 
100000 
$ time git ls-files --others --exclude-standard --error-unmatch \ 
    -- ':/*' >/dev/null 2>/dev/null 

real 0m0.955s 
user 0m0.936s 
sys 0m0.016s 

eliminar este retraso al pasar, además, los '--directory --no-empty-directory' opciones a 'git ls-files' para mostrar sólo el nombre de los directorios sin seguimiento no vacías en vez de todo su contenido:

$ time git ls-files --others --exclude-standard --directory \ 
    --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null 

real 0m0.010s 
user 0m0.008s 
sys 0m0.000s 

Esto sigue el juego de ea95c7b (finalización: mejorar el directorio no rastreado filtrando para la finalización del nombre de archivo, 2013-09-18, git 1.8.5).

Cuestiones relacionadas