gitignore-Vorrang und Negationsmuster (!)
Warum die letzte Regel gewinnt, wie der Vorrang zwischen .gitignore, info/exclude und globaler Konfiguration geregelt ist, und warum ! eine Datei in einem ausgeschlossenen Elternverzeichnis nicht zurückholen kann – samt Lösung.
Wenn gitignore-Regeln sich nicht wie erwartet verhalten, liegt die Ursache fast immer in der Reihenfolge oder im übergeordneten Verzeichnis. Dieser Artikel zeigt, welcher von mehreren Regeln git folgt.
Innerhalb einer Datei: Die zuletzt passende Regel gewinnt
Innerhalb einer .gitignore liest git von oben nach unten, und das zuletzt passende Muster bestimmt das Ergebnis. Beginnt dieses Muster mit !, wird nicht ignoriert, andernfalls schon.
*.log
!important.log
important.log passt auf beide Zeilen, doch die letzte ist eine Negation, daher wird die Datei verfolgt. Kehren Sie die Reihenfolge um, kehrt sich auch das Ergebnis um.
!important.log
*.log
Jetzt ist der letzte Treffer für important.log die Regel *.log, daher wird sie ignoriert. Deshalb gilt beim Zusammenführen mehrerer Vorlagen im Generator: Die Auswahlreihenfolge ist die Regelreihenfolge. Wer etwa *.jar aus der Java-Vorlage zusammen mit !gradle-wrapper.jar aus der Gradle-Vorlage nutzt, muss Gradle nach Java einordnen.
Vorrang zwischen mehreren Dateien
git liest Regeln aus den folgenden vier Quellen. Je weiter oben, desto höher der Vorrang.
- Auf der Befehlszeile übergebene Muster (bei einigen Befehlen wie
git ls-files --exclude) .gitignoreim selben oder einem übergeordneten Verzeichnis des Pfads – eine tiefer liegende Datei überschreibt die übergeordnete$GIT_DIR/info/exclude(meist.git/info/exclude)- Die Datei, auf die die Einstellung
core.excludesFileverweist (globale gitignore)
Steht zum Beispiel *.tmp in der Wurzel-.gitignore und !*.tmp in sub/.gitignore, wird sub/y.tmp gemäß der Negationsregel der tieferen Datei verfolgt. Umgekehrt gilt: Selbst wenn Sie !x in .git/info/exclude schreiben, hat x aus der .gitignore Vorrang, und x bleibt ignoriert.
$ git check-ignore -v x y.tmp sub/y.tmp
.gitignore:1:x x
.gitignore:2:*.tmp y.tmp
sub/.gitignore:1:!*.tmp sub/y.tmp
Die wichtigste Ausnahme: Ein ausgeschlossenes Elternverzeichnis lässt sich nicht zurückholen
Die git-Dokumentation sagt es so: Ist das übergeordnete Verzeichnis einer Datei ausgeschlossen, kann die Datei nicht wieder aufgenommen werden. Aus Leistungsgründen schaut git gar nicht erst in ausgeschlossene Verzeichnisse hinein, sodass !-Regeln für Dateien darin nicht einmal gelesen werden.
logs/
!logs/keep.txt
Mit diesen Regeln bleibt logs/keep.txt ignoriert. git check-ignore -v zeigt logs/ als entscheidende Regel an.
Die Lösung: Schließen Sie nicht das Verzeichnis aus, sondern den Inhalt des Verzeichnisses.
logs/*
!logs/keep.txt
logs/* passt nicht auf das Verzeichnis logs selbst, also steigt git hinein und wendet die Negationsregel auf keep.txt an. /log/* + !/log/.keep in der Rails-Vorlage und .vscode/* + !.vscode/settings.json in der VS-Code-Vorlage beruhen beide auf diesem Prinzip.
Um einen tiefer liegenden Pfad zurückzuholen, müssen Sie auch jedes Zwischenverzeichnis einzeln zurückholen.
config/*
!config/app/
config/app/*
!config/app/defaults.yml
Das Allowlist-Muster
Dasselbe Prinzip gilt, wenn Sie statt der zu ignorierenden Dinge nur das aufzählen wollen, was verfolgt werden soll.
# Alles im Wurzelverzeichnis ignorieren
/*
# Nur das Nötige wieder aufnehmen
!/.gitignore
!/src/
!/README.md
/* passt nur auf die einzelnen Einträge im Wurzelverzeichnis und schließt die Wurzel selbst nicht aus, daher funktioniert !/src/. Bei diesem Ansatz wird auch die .gitignore selbst von /* erfasst – vergessen Sie !/.gitignore nicht. Tatsächlich erscheint .gitignore ohne diese Zeile bei git status --ignored in der Liste der ignorierten Dateien.
Doppelte Regeln und Reihenfolge
Kommt dieselbe Regel mehrmals vor, beeinflusst die frühere Kopie das Ergebnis nicht, denn die spätere passt immer später. Das Löschen einer späteren Kopie kann das Ergebnis dagegen ändern, wenn dazwischen eine Negationsregel steht.
*.log
!debug.log
*.log
Löschen Sie hier das letzte *.log, wird debug.log verfolgt. Der Generator dieser Website erkennt solche Fälle und entfernt spätere Duplikate nur dann, wenn keine Negationsregel dazwischen steht; die übrigen bleiben erhalten.
Quellen
- Offizielle gitignore-Dokumentation: PATTERN FORMAT, NOTES
- Offizielle git-check-ignore-Dokumentation
- Stand der Prüfung: 2026-09-23 (Beispiele mit git 2.50.1 verifiziert)