Git-Befehl, um anzuzeigen, welche bestimmten Dateien von .gitignore ignoriert werden

643

Ich mache meine Füße mit Git nass und habe folgendes Problem:

Mein Projektquellbaum:

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

Ich habe Code (derzeit MEF) in meinem Lieferantenzweig, den ich dort kompilieren und dann die Referenzen verschieben werde, in /src/refsdie das Projekt sie abholt.

Mein Problem ist, dass ich mein .gitignoreSet ignorieren muss *.dllund *.pdb. Ich kann git add -f bar.dlldas Hinzufügen der ignorierten Datei erzwingen, was in Ordnung ist. Das Problem ist, dass ich nicht herausfinden kann, welche Dateien vorhanden sind, die ignoriert werden.

Ich möchte die ignorierten Dateien auflisten, um sicherzustellen, dass ich nicht vergesse, sie hinzuzufügen.

Ich habe die Manpage gelesen git ls-filesund kann sie nicht zum Laufen bringen. Es scheint mir, dass ich git ls-files --exclude-standard -itun sollte, was ich will. Was vermisse ich?

Andrew Burns
quelle
12
Heutzutage
7
Ich bitte Sie, die Antwort von Riad als richtig zu überprüfen, da dies die einzige ist, die zugibt, dass es keine garantierte Möglichkeit gibt, dies nur mit Git-Befehlen (einschließlich des git cleanTricks) zu tun, wie hier gezeigt . Außerdem empfehle ich das Beispiel "Ausschließen von" in Ihrer Zusammenfassung, da dabei keine .gitignore-Dateien berücksichtigt werden. Ich frage dies besonders, weil diese Seite die Top-Antwort von Google ist.
Alexander Bird
Kurzer Hinweis zu "Zusammenfassung der Funktionsweise": Auf der Manpage "Git ls-files" wird erklärt, dass "-i" ausgeschlossene Dateien für die ls-Ausgabe enthält. Ich hatte das gleiche Missverständnis, bis ich "es langsam" las. ;-)
wird
2
Die Antworten sollten in einem Antwortbeitrag und nicht in einer Bearbeitung der Frage enthalten sein.
Flimm
Ich habe git config --global alias.ls ls-files --exclude-standard, und das macht die Antwort auf diese Frage git ls -i.
Bis zum

Antworten:

660

Anmerkungen:


Ebenfalls interessant (in der Antwort von qwertymk erwähnt ), können Sie den Befehl auch verwenden , zumindest unter Unix ( funktioniert nicht in einer CMD- Windows- Sitzung).git check-ignore -v

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

Die zweite zeigt die tatsächliche Regel an, nach der .gitignoreeine Datei in Ihrem Git-Repo ignoriert wird.
Verwenden Sie unter Unix " Was wird rekursiv auf alle Dateien im aktuellen Verzeichnis erweitert? " Und ein bash4 +:

git check-ignore **/*

(oder ein find -execBefehl)

Hinweis: https://stackoverflow.com/users/351947/Rafi B. schlägt in den Kommentaren vor , den (riskanten) Globstar zu vermeiden :

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

Stellen Sie jedoch sicher, dass Sie die Dateien aus dem .git/Unterordner ausschließen.


Ursprüngliche Antwort 42009)

git ls-files -i

sollte funktionieren, außer der Quellcode zeigt an:

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

exc_given ?

Es stellt sich heraus, dass nach dem ein weiterer Parameter benötigt wird, -ium tatsächlich etwas aufzulisten:

Versuchen:

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

(aber das würde nur Ihr zwischengespeichertes (nicht ignoriertes) Objekt mit einem Filter auflisten, so dass das nicht ganz das ist, was Sie wollen)


Beispiel:

$ 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

Tatsächlich finde ich in meiner 'gitignore'-Datei (genannt' exclude ') eine Befehlszeile, die Ihnen helfen könnte:

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]
# *~

Damit....

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

sollte den Trick machen.

Wie in der Manpage ls-files erwähnt , --othersist dies der wichtige Teil, um Ihnen nicht zwischengespeicherte, nicht festgeschriebene, normalerweise ignorierte Dateien anzuzeigen.

--exclude_standardist nicht nur eine Verknüpfung, sondern eine Möglichkeit, alle Standardeinstellungen für "ignorierte Muster" einzuschließen.

exclude-standard
Fügen Sie die Standard-Git-Ausschlüsse hinzu : .git/info/exclude, .gitignorein jedes Verzeichnis und die user's global exclusion file.

VonC
quelle
@VocC, nach meinem Verständnis dieser Tests kann die Antwort, die Sie oben empfehlen, einfach große Mängel aufweisen. Deshalb würde ich normalerweise stattdessen die Antwort von Riad empfehlen .
Alexander Bird
2
Seit Git v2.13.2 Release: git status --ignoredscheint es auch nicht verfolgte Dateien zu zeigen: github.com/git/git/blob/master/Documentation/RelNotes/…
Pau
1
Wow, git check-ignore -v *funktioniert super, da es zeigt, wo die Konfiguration angewendet wurde. Vielen Dank.
Hoang Tran
@MikeD Damit * / funktioniert (oder Sie können es einfach tun **), muss globstar eingestellt werden, shopt -s globstardanach sollte es funktionieren.
Veda
Ohne (riskanten) Globstar zu aktivieren:git check-ignore -v $(find . -type f -print)
Rafi
479

Es gibt einen viel einfacheren Weg, dies zu tun (git 1.7.6+):

git status --ignored

Siehe Gibt es eine Möglichkeit, den Git-Status anzuweisen, die Auswirkungen von Gitignore-Dateien zu ignorieren?

Penghe Geng
quelle
3
Welche Version von Git verwenden Sie? Meins (1.7.0.4) sagt error: unknown option 'ignored'. Selbst das Hinzufügen, -swie im verlinkten Beitrag vorgeschlagen, hat nicht funktioniert.
Alexander Bird
3
Meine Version ist 1.7.6. Eine andere Version 1.7.5.1 ist diejenige, die benötigt wird -s. Sie können versuchen git status -hzu sehen, ob --ignoredunterstützt wird
Penghe Geng
1
Ich denke, das wird in 1.7.0.4 einfach noch nicht unterstützt. Mein anderer Computer hat 1.7.9 und die --ignored Flagge ist da
Alexander Bird
4
Ich habe jede Lösung auf dieser Seite ausprobiert. Dies ist der beste. Es werden sowohl Dateien als auch Verzeichnisse angezeigt. Diese Funktion war wahrscheinlich nicht verfügbar, als diese Frage ursprünglich gestellt wurde. (Übrigens werden alle Lösungen mit einem brandneuen "git init" nicht richtig funktionieren, bis Sie mindestens Änderungen vorgenommen haben.)
wisbucky
12
Dies ist sicherlich viel besser als die akzeptierte Antwort. Es ist auch viel sicherer als die git clean -ndXLösung, da die seltene Situation, in der man versehentlich die Flags vergisst, eine unwiderrufliche Auswirkung auf das Repository hat, da nicht verfolgte Dateien gelöscht werden. Es ist also gefährlich. Im Gegenteil, es git status --ignoredist immer sicher, auch wenn es falsch eingegeben wurde, und es ist natürlich, sich daran zu erinnern.
Ioannis Filippidis
400

Eine andere Option, die ziemlich sauber ist (kein Wortspiel beabsichtigt):

git clean -ndX

Erläuterung:

$ 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.

Hinweis: Diese Lösung zeigt keine ignorierten Dateien an, die bereits entfernt wurden.

ma11hew28
quelle
Nifty ... aber der Grund, warum ich die ursprüngliche Frage gestellt habe, war, dass ich sicherstellen konnte, dass Herstellerdateien (* .dll) vorhanden waren, die vorhanden sein sollten ... daher wäre das Löschen nicht das gewünschte Ergebnis. JEDOCH: Dies ist gut zu wissen, da ich meine Strategie vom Ignorieren von * .dll zum Ignorieren meines Build-Ausgabeordners (aber nicht meiner Herstellerordner) geändert habe. Dies wäre eine gute Alternative zu make cleaneinem Build-Server und auf diesem sehr hilfreich.
Andrew Burns
2
Ich verwende git Version 1.7.0.4 und die beiden Befehle ('git ls-files -o -i --exclude-standard', 'git clean -dXn') sind nicht gleichwertig. Die erste zeigt mir 4 Dateien und die zweite nur zwei. (.gitignore ~, index.php ~, sql / create_users.sql ~, www / index.php ~) (würde .gitignore ~ ​​entfernen, würde index.php ~ entfernen). Vermisse ich hier etwas?
Cesar
@VonC, süß! Vielen Dank! @Cesar, ich bin nicht sicher. Ich bin nicht so vertraut mit git ls-files -o -i --exclude-standard. git clean -dXnwar schon immer das, was ich wollte, zeigt aber keine ignorierten Dateien an, die bereits entfernt wurden. git ls-files -o -i --exclude-standardkönnte das tun. Das könnte also den Unterschied verursachen.
ma11hew28
3
Eine winzige Sache - es könnte eine gute Idee sein, die nerste, weniger zufällige Eingabe auf diese Weise einzugeben. git clean -ndX
Tobias Cohen
1
@TobiasCohen schön! Ich habe die Antwort mit Ihrem Vorschlag aktualisiert. Es ist sicherer. Wenn Sie das nweglassen, wird Git standardmäßig verwendet fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean. Immer noch ziemlich sicher, aber das nerste zu tippen ist noch sicherer! :)
ma11hew28
39

Obwohl im Allgemeinen korrekt, funktioniert Ihre Lösung nicht unter allen Umständen. Nehmen Sie ein Repo-Verzeichnis wie dieses an:

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

doc:
index.html

tmp:
dir0  file1  file2

tmp/dir0:
file0

und ein .gitignore wie dieser:

# cat .gitignore
doc
tmp/*

Dies ignoriert das docVerzeichnis und alle Dateien untentmp . Git funktioniert wie erwartet, der angegebene Befehl zum Auflisten der ignorierten Dateien jedoch nicht. Schauen wir uns an, was git zu sagen hat:

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

Beachten Sie, dass docin der Liste fehlt. Sie können es bekommen mit:

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

Beachten Sie die zusätzlichen --directory Option.

Meines Wissens gibt es keinen einzigen Befehl, um alle ignorierten Dateien gleichzeitig aufzulisten. Aber ich weiß nicht, warum tmp/dir0überhaupt nicht auftaucht.

Riad
quelle
2
Dies brachte mir das, was ich wollte, während die anderen es nicht taten (für meinen speziellen Fall) ... danke! Es ist frustrierend, zwei Befehle ausführen zu müssen, aber bei einem ignorierten Verzeichnis findet mich die Option --directory zumindest, und ich kann das in einen Befehl find umleiten, um die Dateien zu finden. Vielen Dank!
Lindes
Dies macht alles auf einmal und erweitert die Verzeichnisse:(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 hat jetzt diese Funktionalität eingebaut

git check-ignore *

Natürlich können Sie den Globus in etwas wie **/*.dllin Ihrem Fall ändern

Git Referenz

qwertymk
quelle
7
git check-ignore **/*Dateien in Unterverzeichnisse aufnehmen
mzimmer
Hier werden nur die Wörterbücher der obersten Ebene aufgelistet.
Radon8472
13

Es sollte ausreichend sein, um zu verwenden

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

da das alles abdeckt von

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

daher ist letzteres überflüssig.


Sie können dies vereinfachen, indem Sie Ihrer ~/.gitconfigDatei einen Alias ​​hinzufügen :

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

Jetzt können Sie einfach eingeben git ignored, um die Liste anzuzeigen. Viel einfacher zu merken und schneller zu tippen.

Wenn Sie die prägnantere Darstellung der Lösung von Jason Geng bevorzugen, können Sie dafür einen Alias ​​hinzufügen:

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

Die ausführlichere Ausgabe ist jedoch nützlicher für die Behebung von Problemen mit Ihren .gitignore-Dateien, da sie jede einzelne Baumwoll-Pickin-Datei auflistet, die ignoriert wird. Normalerweise leiten Sie die Ergebnisse durch, grepum festzustellen, ob sich dort eine Datei befindet, von der Sie erwarten, dass sie ignoriert wird, oder ob sich dort eine Datei befindet, die Sie nicht ignorieren möchten.

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

Wenn Sie dann nur eine kurze Anzeige sehen möchten, ist es einfach genug, sich zu merken und zu tippen

git status --ignored

(Das -skann normalerweise weggelassen werden.)

Bilderstürmer
quelle
Dies hat bei mir nie funktioniert, da Sie diese Dateien manuell auflisten müssen. git status --ignoredfunktioniert auf Debian Sid, ist aber vielleicht sehr neu… aber anscheinend wurde es aufgrund der großen Nachfrage hinzugefügt
;-)
1
Mit "funktioniert auf Debian Sid" meine ich "funktioniert mit der Version von Git, die standardmäßig auf Debian Sid installiert ist"? Sie sollten wirklich vermeiden, sich von den in Ihrer Distribution enthaltenen Versionen der Dienstprogramme als Geiseln nehmen zu lassen. Sie können sie unabhängig von der Distribution selbst aktualisieren.
Bilderstürmer
12

So drucken Sie die vollständige Liste der Dateien im Arbeitsbaum, die mit Mustern übereinstimmen, die sich an einer beliebigen Stelle in den mehreren Gitignore-Quellen von Git befinden (wenn Sie GNU verwenden find):

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

Es werden alle Dateien im aktuellen Zweig des Repositorys überprüft (es sei denn, Sie haben sie lokal gelöscht).

Und es identifiziert auch die bestimmten Gitignore-Quelllinien.

Git verfolgt weiterhin Änderungen in einigen Dateien, die mit Gitignore-Mustern übereinstimmen, einfach weil diese Dateien bereits hinzugefügt wurden. Nützlicherweise zeigt der obige Befehl auch diese Dateien an.

Negative Gitignore-Muster werden ebenfalls abgeglichen. Diese sind jedoch in der Auflistung leicht zu unterscheiden, da sie mit beginnen !.

Wenn Sie Windows verwenden, enthält Git Bash GNU find(wie von gezeigt find --version).

Wenn die Liste lang ist (und Sie haben rev), können Sie sie auch (etwas) als Erweiterung anzeigen:

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

Weitere Einzelheiten finden Sie man find, man git-check-ignore, man rev, undman sort .

Der Sinn dieses ganzen Ansatzes ist, dass sich Git (die Software) schnell ändert und sehr komplex ist. Im Gegensatz dazu GNU findist extrem stabil (zumindest in den Funktionen hier verwendet wird ). Jeder, der wettbewerbsfähig sein möchte, indem er sein tiefes Wissen über Git zeigt, wird die Frage auf eine andere Weise beantworten.

Was ist die beste Antwort? Diese Antwort minimiert bewusst die Abhängigkeit von Git-Wissen, um das Ziel der Stabilität und Einfachheit durch Modularität (Informationsisolation) zu erreichen, und ist auf eine lange Lebensdauer ausgelegt.

MarkDBlackwell
quelle
Vielen Dank! Ich hatte Mühe herauszufinden, warum einige meiner neuen Quelldateien gelegentlich in meinen Commits fehlten. Es stellt sich heraus, dass ich ein Muster hatte: bin *, von dem ich dachte, dass es nur mit den Namen von Dateien / Verzeichnissen übereinstimmt, die mit bin beginnen, aber stattdessen mit allem, was bin im vollständigen Pfad einer Datei / eines Verzeichnisses enthält! Ich denke, mein Problem ergibt sich aus einem Missverständnis der genauen Semantik des Mustervergleichs in .gitignore. Ihr zweizeiliges Skript hat mir geholfen, diesen Fehler zu finden!
Nicolas Rouquette
1

(Erweiterung der anderen Antworten)

Beachten Sie, dass git check-ignoreder festgeschriebene .gitignoreund nicht der in Ihrem Arbeitsbaum verwendet wird! Um damit zu spielen, ohne Ihren Git-Verlauf zu verschmutzen, können Sie frei versuchen, ihn zu bearbeiten, und dann mit a festschreibengit commit --amend .

Dieses Problem tritt hauptsächlich auf, wenn Sie eine Problemumgehung für das Problem benötigen, dass git keinen Verzeichnissen folgt. Geben Sie Folgendes ein .gitignore:

dirtokeep/**
!dirtokeep/.keep

.keepsollte eine Datei mit der Länge Null sein dirtokeep.

Das Ergebnis ist, dass alles in dirtokeepignoriert wird, außer dirtokeep/.keep dass auch das dirtokeepVerzeichnis beim Klonen / Auschecken erstellt wird.

Peter - Setzen Sie Monica wieder ein
quelle
0

Angenommen, es gibt einige Ignorierverzeichnisse. Warum nicht "git status node / logs /" verwenden, um zu erfahren, welche Dateien hinzugefügt werden sollen? Im Verzeichnis habe ich eine Textdatei, die nicht Teil der Statusausgabe ist, z.

Am Filialstamm
Ihre Filiale ist mit 'Ursprung / Master' auf dem neuesten Stand.
Nicht verfolgte Dateien:
(Verwenden Sie "git add ...", um in das festzuschreiben, was festgeschrieben wird.)

    node/logs/.gitignore 

.gitignore ist:

*

! .gitignore

pikknz
quelle