2012-01-04 7 views
21

¿Existe un comando existente o algún truco o script que me permita mostrar el estado de los archivos que se muestran en "ls"?¿Mejorado "ls" con información de estado de git?

algo como lo siguiente:

$ git ls status #Command could be anything `lsg` is fine too, whatever. 

app   contents modified 
autotest  up-to-date 
config  up-to-date 
config.ru  staged 
db   contents modified 
doc   contents modified 
Gemfile  modified 
Gemfile.lock modified 
lib   up-to-date 
log   up-to-date 
public  up-to-date 
Rakefile  up-to-date 
README  up-to-date 
script  up-to-date 
spec   up-to-date 
tmp   up-to-date 
vendor  contents modidified 
test.tmp  removed 

En ninguna manera: tener la información de estado git disponibles en una lista de directorios.

+5

¿Qué le discute es la ventaja de este formato sobre'Estado' git? – Nate

+1

@Nate: ofrece un mejor birdseye, IMO. Especialmente útil si se cambiaron muchos archivos. Pero también es útil ver los cambios en el contexto de toda la lista de directorios. – berkes

+1

Lo más cercano es probablemente 'git status -s', pero no informará nada más que las modificaciones – fge

Respuesta

10

Utilizando la información de estado de Git short format, aquí hay un script de Bash que usa Awk y el comando column para darle una salida de estado personalizada.

#!/bin/bash 
git status --porcelain | \ 
    awk 'BEGIN {FS=" "} 
{ 
    xstat = substr($0, 1, 1); 
    ystat = substr($0, 2, 1); 
    f = substr($0, 4); 
    ri = index(f, " -> "); 
    if (ri > 0) f = substr(f, 1, ri); 
    if (xstat == " " && ystat ~ "M|D") stat = "not updated"; 
    else if (xstat == "M" && ystat ~ " |M|D") stat = "updated in index"; 
    else if (xstat == "A" && ystat ~ " |M|D") stat = "added to index"; 
    else if (xstat == "D" && ystat ~ " |M") stat = "deleted from index"; 
    else if (xstat == "R" && ystat ~ " |M|D") stat = "renamed in index"; 
    else if (xstat == "C" && ystat ~ " |M|D") stat = "copied in index"; 
    else if (xstat ~ "M|A|R|C" && ystat == " ") stat = "index and work tree matches"; 
    else if (xstat ~ " |M|A|R|C" && ystat == "M") stat = "work tree changed since index"; 
    else if (xstat ~ " |M|A|R|C" && ystat == "D") stat = "deleted in work tree"; 
    else if (xstat == "D" && ystat == "D") stat = "unmerged, both deleted"; 
    else if (xstat == "A" && ystat == "U") stat = "unmerged, added by us"; 
    else if (xstat == "U" && ystat == "D") stat = "unmerged, deleted by them"; 
    else if (xstat == "U" && ystat == "A") stat = "unmerged, added by them"; 
    else if (xstat == "D" && ystat == "U") stat = "unmerged, deleted by us"; 
    else if (xstat == "A" && ystat == "A") stat = "unmerged, both added"; 
    else if (xstat == "U" && ystat == "U") stat = "unmerged, both modified"; 
    else if (xstat == "?" && ystat == "?") stat = "untracked"; 
    else if (xstat == "!" && ystat == "!") stat = "ignored"; 
    else stat = "unknown status"; 
    print f " " stat; 
}' | \ 
    column -t -s " " 

Si crea un archivo ejecutable git-status-ls en un directorio de su PATH ($HOME/bin debería ser un buen lugar), puede escribir git status-ls en cualquier repositorio git. O podrías crear un alias Git alias para esto. También puede implementar esto usando Perl, Python, C o el idioma con el que se sienta más cómodo.


Aquí está un ejemplo de salida:

B        renamed in index 
A        untracked 
dont_delete_git_pre-commit_hook untracked 

acabo de dar cuenta, las pestañas están mostrando como espacios. En el script Awk print f " " stat; y en el comando column -t -s " ", hay una pestaña (no espacios) entre las comillas dobles. Puede usar un separador que no sea tab.


Noté un problema con el manejo de los indicadores de estado en el script anterior y lo corrigí.

+0

Esto no mostrará el "contexto" de los archivos sin modificar. Pero creo que puedo comenzar con esto para agregar todos los demás archivos también. – berkes

+2

Como es, este script simplemente le dirá el estado de lo que podría/podría cometerse. Parecería que el listado de archivos rastreados no modificados requerirá un poco de trabajo; No puedo encontrar una solución rápida. –

-1

Esto debería empezar:

$ (git ls-files -o|sed -e 's/$/ untracked/'; \ 
    git ls-files -m|sed -e 's/$/contents modified/') | 
    sort 

Ver git help ls-files para otras banderas que se pueden utilizar.

Es posible que desee utilizar su interna del shell printf para alinear la salida de la forma en que lo tienes en tu ejemplo:

$ (git ls-files -o|sed -e 's/$/ untracked/'; \ 
git ls-files -m|sed -e 's/$/ contents modified/') | 
    sort | 
    while read file stat 
    do 
     printf "%-30s%-20s\n" $file $stat 
    done 
+0

No veo cómo los archivos git-ls se pueden usar para informar solo sobre el contenido de los directorios; es decir, no mostrar toda la información recursiva – berkes

Cuestiones relacionadas