Comando Git per mostrare quali file specifici vengono ignorati da .gitignore


645

Mi sto bagnando i piedi con Git e ho il seguente problema:

Albero dei sorgenti del mio progetto:

/
|
+--src/
+----refs/
+----...
|
+--vendor/
+----...

Ho un codice (attualmente MEF) nella mia filiale del fornitore che compilerò lì e quindi sposterò i riferimenti in /src/refscui è il progetto da cui li raccoglie.

Il mio problema è che ho il mio .gitignoreset per ignorare *.dlle *.pdb. Posso fare un git add -f bar.dllforzare l'aggiunta del file ignorato che è ok, il problema è che non riesco a capire per elencare quali file esistono che vengono ignorati.

Voglio elencare i file ignorati per assicurarmi di non dimenticare di aggiungerli.

Ho letto la pagina man git ls-filese non riesco a farlo funzionare. Mi sembra che git ls-files --exclude-standard -idovrebbe fare quello che voglio. Cosa mi sto perdendo?


12
In questi giorni, non useresti git-ls-files ma piuttosto 'git ls-files'
wojo

7
Ti supplico di controllare che la risposta di Riyad sia corretta poiché è l'unica che ammette che non esiste un modo garantito per farlo usando solo i comandi git (incluso il git cleantrucco), come dimostrato qui . Inoltre, sconsiglio l'esempio "exclude-from" nel tuo riepilogo poiché in realtà non presta attenzione a nessun file .gitignore. Lo chiedo soprattutto perché questa pagina è la migliore risposta di Google.
Alexander Bird,

Punto rapido su "Riepilogo di ciò che funziona": la pagina man "Git ls-files" spiega che "-i" significa includere i file esclusi per l'output di ls. Ho avuto lo stesso malinteso, fino a quando ho letto "lentamente". ;-)
sarà

2
Le risposte dovrebbero essere inserite in un post di risposta e non in una modifica alla domanda.
Flimm,

Ho git config --global alias.ls ls-files --exclude-standard, e questo rende la risposta a questa domanda git ls -i.
Jill

Risposte:


662

Appunti:


Interessante anche (di cui qwertymk 's risposta ), è anche possibile utilizzare il git check-ignore -vcomando, almeno su Unix ( non funziona in un CMD di Windows sessione)

git check-ignore *
git check-ignore -v *

Il secondo mostra la regola effettiva .gitignoreche rende un file da ignorare nel tuo repository git.
Su Unix, usando " Cosa si espande ricorsivamente a tutti i file nella directory corrente? " E un bash4 +:

git check-ignore **/*

(o un find -execcomando)

Nota: https://stackoverflow.com/users/351947/Rafi B. suggerisce nei commenti di evitare la (rischiosa) globstar :

git check-ignore -v $(find . -type f -print)

Assicurati di escludere i file dalla .git/sottocartella però.


Risposta originale 42009)

git ls-files -i

dovrebbe funzionare, tranne che il codice sorgente indica:

if (show_ignored && !exc_given) {
                fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
                        argv[0]);

exc_given ?

Si scopre che è necessario un altro parametro dopo il -iper elencare effettivamente qualsiasi cosa:

Provare:

git ls-files -i --exclude-from=[Path_To_Your_Global].gitignore

(ma questo elencherebbe solo il tuo oggetto memorizzato nella cache (non ignorato), con un filtro, quindi non è esattamente quello che vuoi)


Esempio:

$ cat .git/ignore
# ignore objects and archives, anywhere in the tree.
*.[oa]
$ cat Documentation/.gitignore
# ignore generated html files,
*.html
# except foo.html which is maintained by hand
!foo.html
$ git ls-files --ignored \
    --exclude='Documentation/*.[0-9]' \
    --exclude-from=.git/ignore \
    --exclude-per-directory=.gitignore

In realtà, nel mio file 'gitignore' (chiamato 'exclude'), trovo una riga di comando che potrebbe aiutarti:

F:\prog\git\test\.git\info>type exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

Così....

git ls-files --others --ignored --exclude-from=.git/info/exclude
git ls-files -o -i --exclude-from=.git/info/exclude

git ls-files --others --ignored --exclude-standard
git ls-files -o -i --exclude-standard

dovrebbe fare il trucco.

Come menzionato nella pagina man ls-files , --othersè la parte importante, al fine di mostrarti i file non memorizzati nella cache, non impegnati, normalmente ignorati.

--exclude_standardnon è solo una scorciatoia, ma un modo per includere tutte le impostazioni standard "schemi ignorati".

exclude-standard
Aggiungere le esclusioni git standard di: .git/info/exclude, .gitignorein ogni directory, e il user's global exclusion file.


@VocC, dalla mia comprensione di questi test , la risposta che consigli all'inizio può semplicemente avere grossi difetti. Ecco perché consiglierei normalmente la risposta di Riyad .
Alexander Bird,

2
Dalla versione di Git v2.13.2: git status --ignoredsembra che mostri anche file non tracciati: github.com/git/git/blob/master/Documentation/RelNotes/…
Pau

1
wow, git check-ignore -v *funziona alla grande, in quanto mostra dove è stata applicata la configurazione. Grazie.
Hoang Tran,

@MikeD Per far funzionare * / (o effettivamente, puoi semplicemente fare **) devi impostare globstar shopt -s globstardopo che dovrebbe funzionare.
Veda,

Senza abilitare (rischioso) globstar:git check-ignore -v $(find . -type f -print)
rafi

484

C'è un modo molto più semplice per farlo (git 1.7.6+):

git status --ignored

Vedi C'è un modo per dire a git-status di ignorare gli effetti dei file .gitignore?


3
Quale versione di Git stai usando? Il mio (1.7.0.4) dice error: unknown option 'ignored'. Anche l'aggiunta -scome suggerito nei post collegati non ha funzionato.
Alexander Bird,

3
La mia versione è la 1.7.6. Un'altra versione 1.7.5.1 è quella che richiede -s. Puoi provare git status -ha vedere se --ignoredè supportato
Penghe Geng,

1
Immagino che semplicemente non sia ancora supportato in 1.7.0.4. L'altro mio computer ha l'1.7.9 e la bandiera --ignored è lì
Alexander Bird il

4
Ho provato tutte le soluzioni in questa pagina. Questo è il migliore. Mostra sia i file che le directory. Questa funzione probabilmente non era disponibile quando questa domanda era stata inizialmente posta. (A proposito, tutte le soluzioni non funzioneranno correttamente con un nuovo "git init" fino a quando non avrai almeno messo in scena le modifiche.)
wisbucky

12
Questo è sicuramente molto meglio della risposta accettata. È anche molto più sicuro della git clean -ndXsoluzione, perché la rara situazione in cui si dimenticano erroneamente i flag avrà un effetto irrevocabile sul repository, poiché i file non tracciati vengono eliminati. Quindi è pericoloso. Al contrario git status --ignoredè sempre sicuro, anche se digitato erroneamente ed è naturale da ricordare.
Ioannis Filippidis,

400

Un'altra opzione che è abbastanza pulita (nessun gioco di parole previsto.):

git clean -ndX

Spiegazione:

$ git help clean

git-clean - Remove untracked files from the working tree
-n, --dry-run - Don't actually remove anything, just show what would be done.
-d - Remove untracked directories in addition to untracked files.
-X - Remove only files ignored by Git.

Nota: questa soluzione non mostrerà i file ignorati che sono già stati rimossi.


Nifty ... tuttavia il motivo per cui ho posto la domanda originale era in modo da poter essere sicuro che i file del fornitore (* .dll) che si supponevano fossero lì ... quindi eliminarli non sarebbe stato il risultato desiderato. TUTTAVIA: è utile sapere che ho cambiato la mia strategia dall'ignorare * .dll all'ignorare la mia cartella di output di compilazione (ma non le mie cartelle del fornitore). Questa sarebbe una buona alternativa make cleane molto utile su un server di build.
Andrew Burns,

2
Sto usando la versione 1.7.0.4 di git, e i due comandi ('git ls-files -o -i --exclude-standard', 'git clean -dXn') non sono equivalenti. Il primo mi mostra 4 file e il secondo solo due. (.gitignore ~, index.php ~, sql / create_users.sql ~, www / index.php ~) (Rimuovere .gitignore ~, Rimuovere index.php ~). Mi manca qualcosa qui?
Cesar,

@VonC, dolce! Grazie! @Cesar, non ne sono sicuro. Non ne ho molta familiarità git ls-files -o -i --exclude-standard. git clean -dXnè sempre stato quello che volevo, ma non mostra i file ignorati che sono già stati rimossi. git ls-files -o -i --exclude-standardpotrebbe farlo. Quindi, questo potrebbe essere ciò che sta causando la differenza.
ma11hew28,

3
Una piccola cosa: potrebbe essere una buona idea digitare la nprima, meno possibilità di cancellare accidentalmente in quel modo; git clean -ndX
Tobias Cohen,

1
@TobiasCohen nice! Ho aggiornato la risposta con il tuo suggerimento. È più sicuro. Anche se, se si esclude n, Git viene impostato automaticamente su fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean. Ancora abbastanza sicuro, ma digitare il nprimo è ancora più sicuro! :)
ma11hew28,

39

Sebbene generalmente corretta, la soluzione non funziona in tutte le circostanze. Assumi un repo dir come questo:

# ls **/*                                                                                                       
doc/index.html  README.txt  tmp/dir0/file0  tmp/file1  tmp/file2

doc:
index.html

tmp:
dir0  file1  file2

tmp/dir0:
file0

e un .gitignore come questo:

# cat .gitignore
doc
tmp/*

Ciò ignora la docdirectory e tutti i file sottostanti tmp. Git funziona come previsto, ma il comando dato per elencare i file ignorati no. Diamo un'occhiata a cosa ha da dire Git:

# git ls-files --others --ignored --exclude-standard                                                            
tmp/file1
tmp/file2

Si noti che docmanca nell'elenco. Puoi ottenerlo con:

# git ls-files --others --ignored --exclude-standard --directory                                                
doc/

Si noti l' --directoryopzione aggiuntiva .

Per quanto ne so, non esiste un comando per elencare tutti i file ignorati contemporaneamente. Ma non so perché tmp/dir0non si presenti affatto.


2
Questo mi ha ottenuto quello che volevo, mentre gli altri no (per il mio caso particolare) ... grazie! È frustrante dover eseguire due comandi, ma con una directory ignorata, l'opzione --directory mi trova almeno quello, e posso inserirlo in un comando find per trovare i file. Grazie!
cade

Questo fa tutto in una volta, ed espande le directory:(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | perl -nle '$seen{$_}++||next;if(-d){system"find",$_,"-type","f"}else{print}'
Dee Newcum,

17

Git ora ha questa funzionalità integrata

git check-ignore *

Ovviamente puoi cambiare il glob in qualcosa come **/*.dllnel tuo caso

Riferimento Git


7
git check-ignore **/*per includere i file nelle sottodirectory
mzimmer

questo elenca solo le dicrettorie di livello superiore.
Radon8472,

13

Dovrebbe essere sufficiente da usare

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

in quanto copre tutto ciò che è coperto da

git ls-files --others -i --exclude-from=.git/info/exclude

quindi quest'ultimo è ridondante.


Puoi semplificarlo aggiungendo un alias al tuo ~/.gitconfigfile:

git config --global alias.ignored "ls-files --others -i --exclude-standard"

Ora puoi semplicemente digitare git ignoredper vedere l'elenco. Molto più facile da ricordare e più veloce da digitare.

Se preferisci la visualizzazione più concisa della soluzione di Jason Geng, puoi aggiungere un alias per questo come questo:

git config --global alias.ignored "status --ignored -s"

Tuttavia, l'output più dettagliato è più utile per la risoluzione dei problemi con i file .gitignore, in quanto elenca ogni singolo file di selezione del cotone che viene ignorato. Normalmente verifichi i risultati grepper vedere se un file che ti aspetti di essere ignorato è lì dentro o se c'è un file che non vuoi ignorare.

git ignored | grep some-file-that-isnt-being-ignored-properly

Quindi, quando vuoi solo vedere un breve display, è abbastanza facile da ricordare e digitare

git status --ignored

( -sNormalmente può essere lasciato fuori.)


Questo non ha mai funzionato per me, perché devi elencare manualmente quei file. git status --ignoredfunziona su Debian Sid ma potrebbe essere molto nuovo ... ma a quanto pare è stato aggiunto a causa della richiesta popolare ;-)
mirabilos

1
Con "funziona su Debian Sid" suppongo che intendi "funziona con la versione di Git installata di default su Debian Sid"? Dovresti davvero evitare di lasciarti tenere in ostaggio dalle versioni delle utility incluse nella tua distribuzione. Puoi aggiornarli indipendentemente dalla distribuzione stessa.
iconoclasta,

12

Ecco come stampare l'elenco completo dei file nell'albero di lavoro che corrispondono ai modelli situati ovunque nelle molteplici fonti gitignore di Git (se stai usando GNU find):

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose

Controllerà tutti i file nel ramo corrente del repository (a meno che tu non li abbia eliminati localmente).

E identifica anche le linee di origine gitignore particolari.

Git continua a tenere traccia delle modifiche in alcuni file che corrispondono ai modelli gitignore, semplicemente perché quei file sono già stati aggiunti. Utilmente, il comando sopra mostra anche quei file.

Anche i pattern negativi gitignore sono abbinati. Tuttavia, questi sono facilmente distinguibili nell'elenco, perché iniziano con !.

Se stai usando Windows, Git Bash include GNU find(come rivelato da find --version).

Se l'elenco è lungo (e ce l'hai rev), puoi anche visualizzarli per estensione (in qualche modo):

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose \
| rev | sort | rev

Per maggiori dettagli, vedere man find, man git-check-ignore, man rev, e man sort.

Il punto di tutto questo approccio è che Git (il software) sta cambiando rapidamente ed è altamente complesso. Al contrario, GNU findè estremamente stabile (almeno, nelle sue funzionalità utilizzate qui). Quindi, chiunque desideri essere competitivo mostrando la propria conoscenza approfondita di Git risponderà alla domanda in modo diverso.

Qual è la risposta migliore? Questa risposta minimizza deliberatamente la sua dipendenza dalla conoscenza di Git, per raggiungere l'obiettivo di stabilità e semplicità attraverso la modularità (isolamento delle informazioni) ed è progettata per durare a lungo .


Molte grazie! Avevo avuto difficoltà a capire perché alcuni dei miei nuovi file di origine a volte mancavano dai miei commit. Ho scoperto che avevo un modello: bin *, che pensavo corrispondesse solo ai nomi di file / directory che iniziano con bin ma invece corrisponde a tutto ciò che include bin nel percorso completo di un file / directory! Immagino che il mio problema provenga da un malinteso sulla semantica precisa della corrispondenza dei modelli in .gitignore. Il tuo script in 2 righe mi ha aiutato a trovare questo errore!
Nicolas Rouquette,

1

(estendendo le altre risposte)

Nota, git check-ignoreusa il commit .gitignoree non quello nel tuo albero di lavoro! Per giocarci senza inquinare la tua cronologia git, potresti provare liberamente a modificarlo e poi impegnarti con a git commit --amend.

Questo problema si verifica principalmente se hai bisogno di una soluzione alternativa al problema, che git non segue le directory. Inserisci in .gitignore:

dirtokeep/**
!dirtokeep/.keep

.keepdovrebbe essere un file di lunghezza zero in dirtokeep.

Il risultato sarà che tutto in dirtokeepverrà ignorato, tranne dirtokeep/.keep , il che comporterà che anche la dirtokeepdirectory sarà costruita su clone / checkout.


0

Supponendo che ci siano alcune directory da ignorare, perché non usare "git status node / logs /" che ti dirà quali file devono essere aggiunti? Nella directory ho un file di testo che non fa parte dell'output di stato, ad esempio:

Su filiale principale La
filiale è aggiornata con "origine / master".
File non monitorati:
(usa "git add ..." per includere in ciò che verrà eseguito il commit)

    node/logs/.gitignore 

.gitignore è:

*

! .gitignore

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.