2013-04-30 15 views
15

Ecco un esempio breve frammento (che è possibile incollare nel terminale Linux), creando un nuovo git repository e l'aggiunta di alcuni file ad esso (usando git versione 1.7.9.5):Lo stato git mostra file di tracciati non modificati/non modificati?

cd /tmp/ 
mkdir myrepo_git 
cd myrepo_git/ 
git init 
git config user.name "Your Name" 
git config user.email [email protected] 
echo "test" > file_tracked_unchanged.txt 
echo "test" > file_tracked_changed.txt 
echo "test" > file_untracked.txt 
git add file_tracked_unchanged.txt 
git add file_tracked_changed.txt 
git commit -m "initial commit" 

Ora, dopo la commit iniziale, voglio cambiare i file file_tracked_changed.txt e mantenere gli altri (qui, solo file_tracked_unchanged.txt) invariato per il prossimo commit. Di seguito è riportato un frammento che dimostra che, e le diverse uscite di git status vs git ls-files (git uscita shell è preceduto da #):

echo "test more" >> file_tracked_changed.txt 

git status -uno 
# # On branch master 
# # Changes not staged for commit: 
# # (use "git add <file>..." to update what will be committed) 
# # (use "git checkout -- <file>..." to discard changes in working directory) 
# # 
# # modified: file_tracked_changed.txt 
# # 
# no changes added to commit (use "git add" and/or "git commit -a") 
git status 
# # On branch master 
# # Changes not staged for commit: 
# # (use "git add <file>..." to update what will be committed) 
# # (use "git checkout -- <file>..." to discard changes in working directory) 
# # 
# # modified: file_tracked_changed.txt 
# # 
# # Untracked files: 
# # (use "git add <file>..." to include in what will be committed) 
# # 
# # file_untracked.txt 
# no changes added to commit (use "git add" and/or "git commit -a") 
git status -uno --short 
# M file_tracked_changed.txt 
git status --short 
# M file_tracked_changed.txt 
# ?? file_untracked.txt 
git ls-files -v 
# H file_tracked_changed.txt 
# H file_tracked_unchanged.txt 

git add file_tracked_changed.txt 

git status -uno 
# # On branch master 
# # Changes to be committed: 
# # (use "git reset HEAD <file>..." to unstage) 
# # 
# # modified: file_tracked_changed.txt 
# # 
# # Untracked files not listed (use -u option to show untracked files) 
git status 
# # On branch master 
# # Changes to be committed: 
# # (use "git reset HEAD <file>..." to unstage) 
# # 
# # modified: file_tracked_changed.txt 
# # 
# # Untracked files: 
# # (use "git add <file>..." to include in what will be committed) 
# # 
# # file_untracked.txt 
git status -uno --short 
# M file_tracked_changed.txt 
git status --short 
# M file_tracked_changed.txt 
# ?? file_untracked.txt 
git ls-files -v 
# H file_tracked_changed.txt 
# H file_tracked_unchanged.txt 

Quello che sto cercando, è un comando che mostrerà tutti i file monitorati in una directory (che fa git ls-files -v), con il loro stato di repository accurato (che non viene mostrato da git ls-files, poiché mostra lo stato H come stato per tutti i file tracciati). Per esempio, mi piacerebbe per ottenere qualcosa di simile al pseudocodice:

git status-tracked 
# M file_tracked_changed.txt 
# . file_tracked_unchanged.txt 

... dove il punto . sarebbe un simbolo che indica un monitorati, ma file non modificato (se non ricordo male, SVN può utilizzare un carattere U per questi).

In definitiva, mi piacerebbe mostrare anche lo stato di tutti i file in una directory, come nel pseudocodice:

git status-tracked-and-untracked 
# M file_tracked_changed.txt 
# . file_tracked_unchanged.txt 
# ?? file_untracked.txt 

... ma è più importante per me per raggiungere lo stato di tutti file tracciati, come nella precedente pseudo git status-tracked.

Qualsiasi comando in git, che già fa qualcosa di simile?

+0

Prova 'git status -sb' – Kartik

+2

Molte grazie per il commento @Kartik - ma quel comando mostra tracked modified + untracked; Sto cercando un comando che mostri tracciato modificato + tracciato non modificato. Saluti! – sdaau

risposta

0
git status -s | egrep -v '^\?\?' 

Questo filtra le linee che iniziano con ??, cioè, i file non monitorate.

+1

Grazie per la risposta, @Andomar - ma sfortunatamente, quel comando non mostra i file tracciati ma non modificati, che è quello che sto chiedendo. Saluti! – sdaau

+1

'git ls-tree --name-status HEAD' dovrebbe fare quello che vuoi, ma ignora silenziosamente la parte' -status' :) – Andomar

+0

Mille grazie, @Andomar - ottimo suggerimento, non avevo idea di 'ls-tree ', ma come dici tu, gli stati non sono mostrati - quindi ho appena postato [una risposta] (http://stackoverflow.com/a/16308182/277826) che" intercala "lo stato da' git's 'status' e 'ls-files'. Saluti! – sdaau

3

Grazie a @Andomar, per la punta git ls-tree; questo è ciò che si vede:

git ls-tree --name-status HEAD 
# file_tracked_changed.txt 
# file_tracked_unchanged.txt 

... ma voglio stati :)

 

OK, ecco una soluzione, chiamando sia ls-files e status, e li interleaving con un po 'di bash analisi:

git ls-files -cdmoskt --abbrev=8 | while read -r line; do \ 
    fn=$(echo "$line" | sed 's/.*\s\(\w\+\)/\1/'); \ 
    st=$(git status -s "$fn" | printf "%-02s " $(sed 's/\([[:print:]]\+\)\s.*/\1/')); \ 
    echo "$st- $line"; \ 
done 

Se si esegue questo come nell'esempio OP, si ottiene:

git ls-files -cdmoskt --abbrev=8 | while read -r line; do fn=$(echo "$line" | sed 's/.*\s\(\w\+\)/\1/'); st=$(git status -s "$fn" | printf "%-02s " $(sed 's/\([[:print:]]\+\)\s.*/\1/')); echo "$st- $line"; done 
# ?? - ? file_untracked.txt 
# M - H 100644 52e7a08e 0 file_tracked_changed.txt 
# - H 100644 9daeafb9 0 file_tracked_unchanged.txt 

... che è fondamentalmente quello che volevo. (Pubblicherò di nuovo qui se ho fortuna nel convertire questo in un alias git).


EDIT: qui come git alias (per ~/.gitconfig):

ls-fstatus = "! cd $PWD/$GIT_PREFIX; git ls-files -cdmoskt --abbrev=8 | while read -r line; do \ 
    fn=$(echo \"$line\" | sed \"s/.*\\s\\([[:print:]]\\+\\)/\\1/\"); \ 
    st=$(git status -s "$fn" | printf \"%-02s \" $(sed \"s/\\([[:print:]]\\+\\)\\s.*/\\1/\")); \ 
    echo \"$st- $line\"; \ 
    done " 

... quindi si può solo chiamare git ls-fstatus in una data directory git repo.

+0

Questo non gestisce i percorsi con spazi. Aggiungendo le virgolette attorno all'argomento per farlo funzionare: 'cd \" $ PWD/$ GIT_PREFIX \ ";' – KeithB

7

Grazie a @sdaau. Ho fatto alcune modifiche in modo che venga eseguito molto più velocemente, e fornisce risultati nello stesso formato come git status:

git ls-files | while read -r line; 
do 
    st=$(git status -s "$line"); 
    if [ -n "$st" ]; then 
     echo "$st"; 
    else 
     echo " $line"; 
    fi; 
done 
+0

^Molto utile, ma ancora un po 'lento, perché esegue un git_status per ogni singolo file. – frnhr

1

Ispirato da @RogerDueck's answer, ho fatto uno script che viene eseguito git ls-files e git status solo una volta. Funziona circa 15 volte più velocemente sul mio repository con ~ 1700 file, poco meno di 2 secondi.

EDIT: aggiunto una serie di correzioni e alcuni Unittests, si trasferisce a GitHub: https://github.com/frnhr/git-fullstatus

Esempio di output:

M some/file 
D another/file 
D more/files/blahblah 
A this/is/an/added/file/i/think 
    an/unchanged_file 
    another/unchanged_file 
Problemi correlati