W3docs

.gitattributes

Lerne die .gitattributes-Datei kennen: Zeilenenden, Diffs, Merge-Strategien und Export-Verhalten pro Dateipfad steuern. Mit Beispielen.

Was .gitattributes bewirkt

Eine .gitattributes-Datei teilt Git mit, wie bestimmte Dateien anhand ihres Pfads behandelt werden sollen. Während .gitignore entscheidet, ob Git eine Datei verfolgt, legt .gitattributes fest, wie Git die verfolgten Dateien behandelt — wie Zeilenenden normalisiert werden, wie Diffs erstellt werden, wie Merges ablaufen und was beim Export geschieht. Die Datei liegt im Repository und wird committet, sodass alle Mitarbeitenden dasselbe Verhalten erhalten, unabhängig von ihrer persönlichen Git-Konfiguration.

Diese Seite behandelt das Dateiformat, die gängigsten Attribute (Normalisierung von Zeilenenden, Markierung von Binärdateien, benutzerdefinierte Diff-/Merge-Treiber und export-ignore), wo Git nach der Datei sucht und wie widersprüchliche Regeln aufgelöst werden.

Dateiformat

Jede Zeile verbindet ein Dateimuster mit einem oder mehreren Attributen:

# pattern        attributes
*.txt            text
*.png            binary
*.sh             text eol=lf

Muster folgen denselben Glob-Regeln wie in .gitignore: * passt auf alles außer /, ** passt über Verzeichnisgrenzen hinweg, ein führendes / verankert das Muster im Verzeichnis der .gitattributes-Datei, und Zeilen, die mit # beginnen, sind Kommentare. Jedes Attribut nach dem Muster hat eine von vier Formen:

  • Setzentext aktiviert das Attribut.
  • Deaktivieren-text deaktiviert es (der führende Bindestrich).
  • Werteol=lf setzt einen bestimmten Wert.
  • Nicht angegeben!text löscht jede frühere Einstellung und überlässt Git den Standardwert.

Wo Git danach sucht

Die meisten Projekte verwenden eine einzige .gitattributes-Datei im Repository-Stammverzeichnis. Git prüft jedoch mehrere Speicherorte, und eine Regel in einem tieferen Verzeichnis überschreibt eine weiter oben:

  • Eine .gitattributes-Datei in einem beliebigen Verzeichnis gilt für Dateien in diesem Verzeichnis und darunter.
  • $GIT_DIR/info/attributes enthält Regeln, die nicht committet werden (lokal für deinen Klon).
  • core.attributesFile (häufig ~/.config/git/attributes) legt benutzerspezifische Standardwerte fest.

Wenn zwei Regeln auf dieselbe Datei passen könnten, gewinnt der spezifischere Pfad; innerhalb einer Datei gewinnt die letzte passende Zeile. Das Ergebnis für einen beliebigen Pfad lässt sich mit git check-attr prüfen:

git check-attr -a README.md
# README.md: text: auto

Zeilenenden normalisieren

Die häufigste Verwendung von .gitattributes besteht darin, das „jede Zeile geändert"-Chaos zu beenden, das entsteht, wenn Windows- und Unix-Entwickler ein gemeinsames Repository nutzen. Dateien als text zu markieren ermöglicht es Git, Zeilenenden im Repository auf LF zu normalisieren und sie beim Checkout zu konvertieren:

* text=auto
*.sh text eol=lf
*.bat text eol=crlf

text=auto lässt Git entscheiden, welche Dateien Textdateien sind, und speichert sie im Repository mit LF; die expliziten eol-Einstellungen erzwingen beim Checkout ein bestimmtes Zeilenende für Dateien, die eines benötigen (Shell-Skripte müssen bei LF bleiben, Windows-Batch-Dateien bei CRLF). Da die Regeln committet sind, ist das zuverlässiger, als sich auf die core.autocrlf-Einstellung jedes Entwicklers zu verlassen, die von Rechner zu Rechner unterschiedlich ist.

Wenn du * text=auto zu einem bestehenden Repository hinzufügst, werden bereits mit CRLF committete Dateien nicht automatisch renormalisiert. Führe eine einmalige Bereinigung durch, damit der nächste Commit sie korrigiert:

git add --renormalize .
git commit -m "Normalize line endings"

Dateien als binär markieren

Git mitzuteilen, dass eine Datei binär ist, verhindert, dass es versucht, einen textuellen Diff zu erstellen oder sie zeilenweise zu mergen:

*.pdf binary
*.png binary

Das binary-Attribut ist ein eingebautes Makro, das zu -text -diff expandiert und damit die Zeilenenden-Konvertierung sowie das textuelle Diff deaktiviert. Das verhindert, dass Git eine Datei durch Zeilenenden-Umschreibungen beschädigt, und unterbindet, dass git diff unlesbaren Byte-Brei ins Terminal ausgibt.

Bei großen Binärdateien wie Videos, Datensätzen oder Design-Dateien reicht die Markierung als binär nicht aus — sie blähen weiterhin den Verlauf des Repositorys auf. Speichere diese stattdessen mit Git LFS, wofür .gitattributes ebenfalls zur Konfiguration genutzt wird.

Benutzerdefiniertes Diff- und Merge-Verhalten

.gitattributes kann bestimmte Dateien durch benutzerdefinierte Diff- oder Merge-Treiber leiten, doch muss ein benutzerdefinierter Treiber zuerst in der Git-Konfiguration definiert werden — das Attribut referenziert ihn lediglich beim Namen.

Ein häufiger Fall ist eine generierte Lock-Datei: Bei einem Merge-Konflikt möchte man die eigene Branch-Version vollständig behalten, statt sie zeilenweise zu mergen. Registriere einmalig einen ours-Treiber und verweise dann den Pfad darauf:

git config merge.ours.driver true
# .gitattributes
package-lock.json merge=ours

driver auf true zu setzen bedeutet: „Der Merge gelingt immer und das Ergebnis ist die Version des aktuellen Branches." (Dieses dateibezogene merge=ours-Attribut ist unabhängig von der -s ours-Merge-Strategie, die auf einen gesamten Merge angewendet wird.)

Ein benutzerdefinierter Diff-Treiber funktioniert auf dieselbe Weise und ist praktisch für Nicht-Textformate. Git liefert außerdem eingebaute Diff-Treiber, die aussagekräftige Hunk-Header für verbreitete Sprachen erzeugen, sodass ein Diff zeigt, welche Funktion sich geändert hat:

*.c diff=cpp
*.py diff=python

Unter git diff erfährst du, wie diese Treiber die Ausgabe gestalten.

Export-ignore

Wenn jemand ein Release-Archiv über git archive herunterlädt, möchte man Entwicklungsdateien häufig weglassen. Das Attribut export-ignore erledigt genau das:

/tests       export-ignore
/.github     export-ignore
.gitattributes export-ignore

So bleiben Test-Suites, CI-Konfigurationen und Editor-Dateien aus dem Tarball, den git archive erzeugt, heraus, sodass Nutzer nur das herunterladen, was sie benötigen. Ein verwandtes Attribut, export-subst, ersetzt Platzhalter wie $Format:%H$ in exportierten Dateien, sodass ein Archiv den Commit festhalten kann, aus dem es erstellt wurde.

Häufige Attribute

AttributWirkung
textNormalisiert Zeilenenden im Repository auf LF.
eol=lf / eol=crlfErzwingt ein bestimmtes Zeilenende beim Checkout.
binaryBehandelt die Datei als binär — kein Diff, keine Zeilenenden-Konvertierung.
merge=<driver>Verwendet eine benutzerdefinierte Merge-Strategie für die Datei.
diff=<driver>Verwendet einen benutzerdefinierten Diff-Treiber.
export-ignoreSchließt den Pfad aus git archive-Exporten aus.
export-substExpandiert $Format:…$-Platzhalter in archivierten Dateien.

Wann man es verwendet

Greife auf .gitattributes zurück, wenn das dateibezogene Verhalten von Git für alle im Team gleich sein soll, anstatt es lokalen Einstellungen zu überlassen. Die alltäglichen Vorteile sind: Zeilenenden in gemischten Windows/Unix-Teams normalisieren, nutzlose Diffs bei Binärdateien unterdrücken und Release-Archive verkleinern. Die fortgeschrittenen Vorteile — benutzerdefinierte Merge-/Diff-Treiber und Git LFS — lösen spezifische Probleme, sobald ein Projekt auf sie trifft. Beginne mit * text=auto und füge Regeln hinzu, sobald konkrete Probleme auftreten.

Übungen

Übung
Was steuert die '.gitattributes'-Datei?
Was steuert die '.gitattributes'-Datei?
Was this page helpful?