Git teilt jede Datei in eine der folgenden drei Kategorien ein:

  1. Verfolgt: Eine Datei, die bereits in die Staging-Umgebung verschoben oder committet wurde
  2. untracked - a file which has not been staged or committed; or
  3. Ignoriert: Eine Datei, die von Git ausdrücklich ignoriert werden soll

Zu ignorierende Dateien sind normalerweise Build-Artefakte und maschinell generierte Dateien, die von deiner Repository-Quelle abgeleitet werden können oder aus anderen Gründen nicht committet werden sollen. Einige gebräuchliche Beispiele:

  • Abhängigkeits-Caches wie die Inhalte von /node_modules oder /packages
  • Kompilierter Code wie .o-, .pyc- und .class-Dateien
  • Build-Ausgabeverzeichnisse wie /bin, /out oder /target
  • Während der Laufzeit generierte Dateien wie .log, .lock oder .tmp
  • Versteckte Systemdateien wie .DS_Store oder Thumbs.db
  • Persönliche IDE-Konfigurationsdateien wie .idea/workspace.xml

Ignorierte Dateien werden in einer speziellen Datei namens .gitignore verfolgt, die im Root-Verzeichnis deines Repositorys eingecheckt wird. Es gibt keinen expliziten "git ignore"-Befehl: Stattdessen muss die .gitignore-Datei manuell bearbeitet und committet werden, wenn neue Dateien hinzukommen, die ignoriert werden sollen. .gitignore-Dateien enthalten Muster, die mit den Dateinamen in deinem Repository abgeglichen werden, um zu bestimmen, ob diese ignoriert werden sollen oder nicht.

"git ignore"-Muster

.gitignore nutzt Globbing-Muster zur Abgleichung der Dateinamen. Du kannst deine Muster mithilfe verschiedener Symbole erstellen:

Muster Beispiele für Übereinstimmungen Erklärung*
**/logs logs/debug.log
logs/monday/foo.bar
build/logs/debug.log
Zum Abgleichen mit Verzeichnissen überall im Repository stellst du einem Muster ein doppeltes Sternsymbol voran.
**/logs/debug.log logs/debug.log
build/logs/debug.log
aber nicht
logs/build/debug.log
Auch zum Abgleichen von Dateien auf Basis ihres Namen und dem Namen ihres übergeordneten Verzeichnissen kann ein doppeltes Sternsymbol verwendet werden.
*.log debug.log
foo.log
.log
logs/debug.log
Ein Sternsymbol ist eine Wildcard, die mit null oder mehr Zeichen übereinstimmt.
*.log
!important.log
debug.log
trace.log
aber nicht
important.log
logs/important.log
Ein vorangestelltes Ausrufezeichen negiert ein Muster. Wenn eine Datei mit einem Muster übereinstimmt, aber auch mit einem negierendem Muster, das später in der Datei definiert wurde, wird diese nicht ignoriert.
*.log
!important/*.log
trace.*
debug.log
important/trace.log
aber nicht
important/debug.log
Muster, die nach einem negierenden Muster definiert wurden, führen dazu, dass die zuvor negierten Dateien wieder ignoriert werden.
/debug.log debug.log
aber nicht
logs/debug.log
Bei einem vorangestellten Schrägstrich werden nur Dateien im Root-Verzeichnis des Repositorys abgeglichen.
debug.log debug.log
logs/debug.log
Standardmäßig werden die Muster mit Dateien aller Verzeichnisse abgeglichen.
debug?.log debug0.log
debugg.log
aber nicht
debug10.log
Ein Fragezeichen stimmt mit genau einem Zeichen überein.
debug[0-9].log debug0.log
debug1.log
aber nicht
debug10.log
Zum Abgleichen eines einzigen Zeichens eines bestimmten Bereichs können auch eckige Klammern genutzt werden.
debug[01].log debug0.log
debug1.log
aber nicht
debug2.log
debug01.log
Eckige Klammern stimmen mit einem einzigen Zeichen aus der angegebenen Auswahl überein.
debug[!01].log debug2.log
aber nicht
debug0.log
debug1.log
debug01.log
Mit einem Ausrufezeichen werden alle außer den in der Klammer angegebenen Zeichen abgeglichen.
debug[a-z].log debuga.log
debugb.log
aber nicht
debug1.log
Bereiche können numerisch oder alphabetisch sein.
logs logs
logs/debug.log
logs/latest/foo.bar
build/logs
build/logs/debug.log
Wenn du keinen Schrägstrich ans Ende setzt, gleicht das Muster beide Dateien und die Inhalte der Verzeichnisse mit diesem Namen ab. In den Beispielübereinstimmungen links werden die beiden Verzeichnisse und Dateien namens logs ignoriert.
logs/ logs/debug.log
logs/latest/foo.bar
build/logs/foo.bar
build/logs/latest/debug.log
Ein Schrägstrich am Ende kennzeichnet das Muster als ein Verzeichnis. Alle Inhalte aus jedem Verzeichnis im Repository inklusive aller Dateien und Unterkategorien darin, die mit diesem Namen übereinstimmen werden ignoriert.
logs/
!logs/important.log
logs/debug.log
logs/important.log
Moment mal! Sollte logs/important.log im Beispiel links negiert werden?

Nein! Aufgrund einer Performance-bezogenen Eigenheit von Git, kann eine Datei, die infolge einer Übereinstimmung eines Musters mit einem Verzeichnis ignoriert wird, nicht negiert werden.
logs/**/debug.log logs/debug.log
logs/monday/debug.log
logs/monday/pm/debug.log
Ein doppeltes Sternsymbol gleicht null oder mehr Verzeichnisse ab.
logs/*day/debug.log logs/monday/debug.log
logs/tuesday/debug.log
aber nicht
logs/latest/debug.log
Wildcards können auch in Verzeichnisnamen genutzt werden.
logs/debug.log logs/debug.log
aber nicht
debug.log
build/logs/debug.log
Muster, die eine Datei in einem bestimmten Verzeichnis spezifizieren, beziehen sich auf das Root-Verzeichnis des Repositorys. (Du kannst einen Schrägstrich voranstellen, wenn du möchtest, aber dieser hat hier keine Funktion.)

** Diese Erklärungen setzen voraus, dass sich deine .gitignore-Datei im Verzeichnis der obersten Ebene deines Repositorys befindet, wie es allgemein üblich ist. Wenn sich in deinem Repository mehrere .gitignore-Dateien befinden, ersetzt du einfach im Kopf "Root-Verzeichnis des Repositorys" mit "Verzeichnis mit der .gitignore-Datei" (und ziehst eine Zusammenführung in Betracht, um dein Team nicht um den Verstand zu bringen).*

Zusätzlich zu diesen Zeichen kannst du mit # Kommentare in deine .gitignore-Datei eingeben:

# ignore all logs
*.log

Wenn es in deinen Dateien oder Verzeichnissen Zeichen gibt, die dem Muster nach .gitignore entsprechen, kannst du diese mit \ ausschließen:

# ignore the file literally named foo[01].txt
foo\[01\].txt

Gemeinsame .gitignore-Dateien in deinem Repository

Die Regeln für "git ignore" werden normalerweise in einer .gitignore-Datei im Root-Verzeichnis deines Repositorys definiert. Du kannst aber auch mehrere .gitignore-Dateien in verschiedenen Verzeichnissen in deinem Repository definieren. Jedes Muster in einer .gitignore-Datei wird im Abgleich mit dem Verzeichnis, das diese Datei enthält, getestet. Üblich und am einfachsten ist es jedoch, eine einzige .gitignore-Datei im Root-Verzeichnis zu definieren. Beim Einchecken wird deine .gitignore-Datei genauso versioniert wie alle anderen Dateien in deinem Repository und wenn du einen Push durchführst, mit deinen Teamkollegen geteilt. In der Regel sollte .gitignore nur Muster enthalten, die anderen Benutzern des Repositorys von Nutzen sind.

Persönliche Regeln für Git ignore

Außerdem kannst du in einer eigenen Datei unter .git/info/exclude persönliche ignore-Muster für ein bestimmtes Repository definieren. Diese sind nicht versioniert und werden nicht mit deinem Repository verteilt, sodass hier Muster enthalten sein können, die ausschließlich für dich nützlich sind. Wenn beispielsweise deine Protokollierungseinstellungen benutzerdefiniert sind oder du über spezielle Entwicklertools verfügst, die Dateien im Arbeitsverzeichnis deines Repositorys erzeugen, könntest du diese ggf. zu .git/info/exclude hinzufügen, damit sie nicht versehentlich in dein Repository committet werden.

Globale Regeln für Git ignore

Außerdem kannst du in deinem lokalen System globale "git ignore"-Muster für alle Repositorys definieren, indem du die Git-Eigenschaft core.excludesFile einrichtest. Diese Datei musst du selbst erstellen. Falls du dir nicht sicher bist, wo du deine globale .gitignore-Datei am besten ablegst, kannst du mit deinem Startverzeichnis eigentlich nichts falsch machen (und du findest es später problemlos wieder). Nachdem du die Datei erstellt hast, musst du mit git config den Ort konfigurieren:

$ touch ~/.gitignore
$ git config --global core.excludesFile ~/.gitignore

Überlege dir genau, welche Muster global ignoriert werden sollen, denn für verschiedene Projekte sind unterschiedliche Dateitypen relevant. Zu global ignorierbaren Dateien zählen typischerweise bestimmte Betriebssystemdateien (z. B. .DS_Store und thumbs.db) oder temporäre Dateien, die von einigen Entwickler-Tools generiert werden.

Ignorieren einer zuvor committeten Datei

Wenn du eine bereits committete Datei ignorieren willst, musst du diese aus deinem Repository löschen und dann eine .gitignore-Regel dafür hinzufügen. Die Option --cached als Ergänzung zu git rm bewirkt das Löschen der Datei aus deinem Repository. Die Datei bleibt jedoch in deinem Arbeitsverzeichnis und wird ignoriert.

$ echo debug.log >> .gitignore
  
$ git rm --cached debug.log
rm 'debug.log'
  
$ git commit -m "Start ignoring debug.log"

Wenn du die Datei sowohl aus dem Repository als auch aus deinem lokalen Dateisystem löschen willst, kannst du die Option --cached auslassen.

Committen einer ignorierten Datei

Es ist möglich, mit -f (oder --force) in Kombination mit git add den Commit einer ignorierten Datei in das Repository zu erzwingen:

$ cat .gitignore
*.log
  
$ git add -f debug.log
  
$ git commit -m "Force adding debug.log"

Dies ist sinnvoll, wenn du allgemeine Muster (wie *.log) definiert hast, aber eine bestimmte Datei committen möchtest. Die bessere Lösung hierfür ist jedoch eine Ausnahme für die allgemeine Regel zu definieren:

$ echo !debug.log >> .gitignore
  
$ cat .gitignore
*.log
!debug.log
  
$ git add debug.log
  
$ git commit -m "Adding debug.log"

Diese Vorgehensweise ist naheliegender und weniger verwirrend für deine Teamkollegen.

Verschieben einer ignorierten Datei in den Stash

git stash ist ein starkes Git-Feature, mit dem du lokale Änderungen temporär aufschieben und rückgängig machen, sie später aber auch wieder anwenden kannst. Wie zu erwarten ist, ignoriert git stash ignorierte Dateien standardmäßig und stasht nur Änderungen an Dateien, die mit Git verfolgt werden. Wenn du allerdings git stash mit der Option --all ausführst, werden auch Änderungen an ignorierten und nicht verfolgten Dateien gestasht.

Debugging von .gitignore-Dateien

Bei komplexen .gitignore-Mustern und Mustern, die über mehrere .gitignore-Dateien verteilt sind, ist es eventuell schwierig festzustellen, warum eine bestimmte Datei ignoriert wird. Mit dem Befehl git check-ignore und der Option -v (oder --verbose) kannst du herausfinden, auf welches Muster das Ignorieren einer Datei zurückgeht:

$ git check-ignore -v debug.log
.gitignore:3:*.log  debug.log

In der Ausgabe ist Folgendes zu sehen:

<file containing the pattern> : <line number of the pattern> : <pattern>    <file name>

Wenn nötig kannst du mehrere Dateinamen zu git check-ignore angeben. Die Namen müssen dabei nicht mit bestehenden Dateien in deinem Repository übereinstimmen.

Du möchtest mit Git arbeiten?

Sieh dir dieses interaktive Tutorial an.

Jetzt loslegen