Git LFS: große Dateien in einem Git-Repository speichern
Git LFS (Large File Storage) ist eine Git-Erweiterung, die große Binärdateien auf einem separaten Server ablegt und im Repository nur kleine Pointer-Dateien speichert. Das Klonen wird schnell, die Historie bläht sich nicht auf, und die Arbeit mit den Dateien bleibt wie gewohnt: git add, commit und push.
Was ist Git LFS und wofür braucht man es?
Git LFS (Large File Storage) ist die offizielle Git-Erweiterung zum Speichern großer Dateien: Videos, PSD-Layouts, Datensätze, Modelle neuronaler Netze, Game-Assets. Statt der Datei selbst landet im Commit ein Text-Pointer von etwa 130 Byte, der Inhalt wandert in einen separaten LFS-Speicher auf dem Server. Beim Checkout setzt die Erweiterung die echte Datei ins Arbeitsverzeichnis ein – für Sie sieht alles aus wie normales Git.
Das Problem, das git lfs löst, liegt in der Funktionsweise von Git selbst. Jede Version jeder Datei bleibt für immer in der Historie, und beim Klonen wird die gesamte Historie heruntergeladen. Wenn Sie ein 200-MB-Video zehnmal geändert haben, wiegt das Repository bereits rund 2 GB, und jeder neue Entwickler lädt alle zehn Versionen herunter, auch wenn er nur die letzte braucht. Kompression und Deltas, die bei Text gut funktionieren, bringen bei Binärdateien kaum etwas.
Mit LFS werden beim Klonen nur die Versionen großer Dateien für den aktuellen Commit geladen. Ältere Versionen liegen auf dem Server und werden nachgeladen, wenn Sie zu einem alten Commit wechseln.
So funktioniert Git LFS intern
Der Mechanismus basiert auf Git-Filtern – clean und smudge. Wenn Sie git add auf eine von LFS getrackte Datei ausführen, greift der clean-Filter: Er legt den Inhalt im lokalen Cache .git/lfs/objects ab und übergibt dem Index einen Pointer. Beim Checkout macht der smudge-Filter das Gegenteil: Er sucht das Objekt anhand des Hashs im Cache (oder lädt es vom Server) und schreibt die echte Datei.
Ein Pointer sieht so aus:
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 209715200
Drei Zeilen: Version der Spezifikation, SHA-256 des Inhalts und Größe in Byte. Genau das wird in der Git-Historie gespeichert, deshalb bleibt sie schlank. Bei git push greift ein pre-push-Hook: Zuerst werden neue Objekte über die LFS-API hochgeladen, dann die Commits über das normale Protokoll übertragen.
Welche Dateien LFS übernimmt, legt die Datei .gitattributes im Wurzelverzeichnis des Repositorys fest. Sie wird zusammen mit dem Code committet, daher gelten für das ganze Team dieselben Regeln.
Git LFS installieren
In Git für Windows ist die Erweiterung bereits im Installer enthalten. Unter macOS und Linux installieren Sie sie als Paket:
# macOS (Homebrew)
brew install git-lfs
# Debian / Ubuntu
sudo apt install git-lfs
# Fedora
sudo dnf install git-lfs
Führen Sie nach der Installation einmal pro Benutzer aus:
git lfs install
Der Befehl trägt die LFS-Filter in die globale ~/.gitconfig ein und installiert Hooks im aktuellen Repository, falls Sie sich in einem befinden. Ob alles da ist, prüfen Sie mit git lfs version; die ausführliche Konfiguration (Serveradresse, Cache-Pfade) zeigt git lfs env.
Große Dateien mit git lfs track verfolgen
Typisches Vorgehen in einem neuen Projekt:
git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "models/**"
git add .gitattributes
git add design/banner.psd
git commit -m "Banner-Layout über LFS hinzufügen"
git push origin main
Die Anführungszeichen um das Muster sind Pflicht: Ohne sie expandiert die Shell *.psd selbst zu einer Liste der Dateien im aktuellen Ordner, und die Regel wird falsch. Nach git lfs track erscheint in .gitattributes die Zeile:
*.psd filter=lfs diff=lfs merge=lfs -text
Das Attribut -text deaktiviert die Umwandlung von Zeilenenden, die eine Binärdatei beschädigen würde. Die Reihenfolge ist wichtig: zuerst die track-Regel, dann git add der Datei. Wurde die Datei bereits vor der Regel normal hinzugefügt, ist sie als gewöhnlicher Blob in der Historie geblieben.
Prüfen, ob eine Datei wirklich in LFS liegt
git lfs ls-files
4d7a214614 * design/banner.psd
9c1e0b7a3f * video/intro.mp4
git lfs status
git lfs ls-files zeigt die in LFS gespeicherten Dateien des aktuellen Commits. Ein Sternchen bedeutet, dass der Inhalt heruntergeladen ist, ein Bindestrich, dass in der Arbeitskopie nur der Pointer liegt. Die Liste der Tracking-Muster gibt git lfs track ohne Argumente aus; eine Regel entfernen Sie mit git lfs untrack "*.psd".
Klonen und Dateien abrufen
Ein normales git clone funktioniert mit LFS transparent: Ist die Erweiterung installiert, werden große Dateien automatisch heruntergeladen. Hat ein Kollege LFS nicht installiert, sieht er in der Arbeitskopie Text-Pointer statt Bildern – das häufigste Symptom nach dem Motto „statt der PSD habe ich irgendeinen Text“. Abhilfe schaffen die Installation und der Befehl:
git lfs install
git lfs pull
git lfs pull lädt die Objekte für den aktuellen Commit herunter und setzt sie ins Arbeitsverzeichnis ein. Daneben gibt es git lfs fetch – er lädt nur in den Cache, ohne die Dateien anzufassen. Mit dem Flag --all holt er die Objekte für alle Referenzen, was sich für ein vollständiges Backup oder einen Umzug auf einen anderen Server eignet.
Klonen ohne große Dateien
In der CI oder wenn Sie nur den Code brauchen, ist das Herunterladen von Gigabytes an Assets überflüssig. Eine Umgebungsvariable deaktiviert den smudge-Filter:
GIT_LFS_SKIP_SMUDGE=1 git clone https://example.com/team/game.git
cd game
git lfs pull --include="textures/ui/**"
Das Repository wird mit Pointern geklont, anschließend holen Sie gezielt die benötigten Dateien über --include (es gibt auch --exclude). Das beschleunigt Builds in Pipelines deutlich.
Bestehende Dateien nach Git LFS migrieren
Eine häufige Situation: Das Repository ist bereits aufgebläht, große Dateien liegen in der Historie. git lfs track wirkt nicht rückwirkend – nur auf neue Commits. Um die Historie umzuschreiben, verwenden Sie git lfs migrate.
Ermitteln Sie zuerst, was Platz belegt:
git lfs migrate info --everything --top=10
Migrieren Sie dann die gewünschten Dateitypen in allen Branches:
git lfs migrate import --include="*.psd,*.mp4" --everything
git push --force --all
git push --force --tags
Die Migration schreibt jeden Commit um, in dem diese Dateien vorkamen – also ändern sich alle Hashes. Es ist dieselbe Geschichte wie beim Rebase veröffentlichter Branches: Alle Beteiligten müssen informiert werden, nach dem Force-Push sollten sie das Repository neu klonen oder ihre Branches hart zurücksetzen. Erstellen Sie vor der Migration eine Sicherung (git clone --mirror).
Wenn die Historie nicht umgeschrieben werden darf, gibt es eine sanfte Variante: git lfs migrate import --no-rewrite pfad/zur/datei. Sie erzeugt einen neuen Commit, der die Dateien ab diesem Zeitpunkt in LFS überführt. Alte Versionen bleiben in der Historie, aber das Repository wächst nicht weiter.
File Locking: Konflikte bei Binärdateien vermeiden
Zwei Designer bearbeiten dieselbe PSD – und Git kann ihre Änderungen nicht zusammenführen, eine Arbeit geht verloren. Für solche Dateien bietet LFS Sperren. Markieren Sie den Typ als sperrbar:
git lfs track "*.psd" --lockable
In .gitattributes kommt das Attribut lockable hinzu, und solche Dateien sind in der Arbeitskopie schreibgeschützt, bis Sie sie sperren:
git lfs lock design/banner.psd
git lfs locks
design/banner.psd anna ID:123
# nach dem Push der Änderungen
git lfs unlock design/banner.psd
Solange die Datei gesperrt ist, wird ein Push von Änderungen daran durch eine andere Person abgelehnt. Sperren werden vom Server unterstützt, daher funktionieren sie bei großen Git-Hostern, auf einem selbstgebauten Server fehlen sie aber womöglich. Ein Administrator kann eine fremde Sperre mit git lfs unlock --force aufheben.
Wo LFS-Objekte gespeichert werden und was es kostet
LFS-Objekte liegen auf einem Server, der die LFS-API unterstützt. Diese implementieren populäre Git-Hoster und Self-Hosted-Lösungen sowie eigenständige Server. Cloud-Hoster haben Limits für Speicherplatz und LFS-Traffic, die je nach Dienst und Tarif variieren – prüfen Sie die aktuellen Bedingungen Ihrer Plattform, bevor Sie Datensätze mit Hunderten Gigabyte hochladen.
Beachten Sie, dass der Traffic bei jedem Download zählt: Eine CI, die bei jedem Commit ein Repository mit LFS-Dateien klont, kann das Limit schneller ausschöpfen als Menschen. Cachen Sie .git/lfs zwischen Builds oder nutzen Sie GIT_LFS_SKIP_SMUDGE.
Auch lokal wächst der Cache. Der Befehl git lfs prune löscht alte Objekte, die bereits auf dem Server liegen und für aktuelle und kürzliche Commits nicht gebraucht werden.
Wann Git LFS passt und wann nicht
| Situation | Passt LFS? | Kommentar |
|---|---|---|
| Game-Assets, Layouts, Audio, Video | Ja | Klassischer Fall: Binärdateien, die sich oft ändern |
| ML-Modelle und mittelgroße Datensätze neben dem Code | Ja, mit Blick auf die Kontingente | Für sehr große Daten sind spezialisierte Werkzeuge zur Datenversionierung praktischer |
| Kompilierte Build-Artefakte | Nein | Sie gehören in eine Artefakt-Registry oder in Releases, nicht in Git |
| Abhängigkeiten (node_modules, vendor) | Nein | Werden vom Paketmanager installiert, tragen Sie sie in .gitignore ein |
| Große Textdateien (SQL-Dumps, CSV) | Kommt darauf an | Text speichert Git effizient als Deltas; LFS lohnt sich, wenn die Dateien riesig und im Diff kaum lesbar sind |
| Secrets und private Schlüssel | Niemals | LFS verschlüsselt keine Daten, es ist kein Secret-Speicher |
Typische Fehler und ihre Lösung
In der Arbeitskopie liegt statt der Datei ein Text-Pointer
LFS ist nicht installiert, oder es wurde mit GIT_LFS_SKIP_SMUDGE=1 geklont. Führen Sie git lfs install und git lfs pull aus.
Eine Datei ist an LFS vorbei in die Historie gelangt
Die track-Regel wurde nach git add hinzugefügt. Ist der Commit noch nicht gepusht, nehmen Sie die Datei aus dem Index (git rm --cached datei), stellen sicher, dass die Regel in .gitattributes steht, und fügen sie erneut hinzu. Ist er bereits gepusht – git lfs migrate import. Solche Dateien findet git lfs fsck --pointers.
Push wird wegen der Dateigröße abgelehnt
Viele Hoster begrenzen die Größe eines einzelnen Objekts im normalen Git. Eine Meldung wie „this exceeds the file size limit“ bedeutet, dass die Datei in LFS gehört hätte. Schreiben Sie den letzten Commit oder die Historie wie oben beschrieben um – ein einfacher Commit „Datei löschen“ hilft nicht, sie bleibt in den vorherigen Commits.
Nach git lfs migrate ist bei den Kollegen alles kaputt
Ihre lokalen Branches basieren auf den alten Hashes. Am zuverlässigsten ist es, das Repository neu zu klonen; gibt es noch nicht gepushte Arbeit, übertragen Sie sie per cherry-pick auf die neuen Branches.
Git LFS Cheat Sheet
| Befehl | Was er tut |
|---|---|
git lfs install | Richtet Filter und Hooks ein |
git lfs track "*.ext" | Fügt ein Muster zu .gitattributes hinzu |
git lfs untrack "*.ext" | Entfernt ein Muster |
git lfs ls-files | Dateien in LFS für den aktuellen Commit |
git lfs pull | Objekte herunterladen und einsetzen |
git lfs fetch --all | Objekte aller Referenzen in den Cache laden |
git lfs migrate import --include="..." --everything | Dateien aus der Historie nach LFS migrieren |
git lfs lock / unlock / locks | Arbeit mit Sperren |
git lfs prune | Lokalen Cache von alten Objekten bereinigen |
git lfs env | Diagnose der Einstellungen |
Fazit
Git LFS lagert große Binärdateien aus der Historie in einen separaten Speicher aus und lässt in den Commits nur schlanke Pointer zurück. Die wichtigste Regel: git lfs track vor dem ersten Commit großer Dateien einrichten, .gitattributes committen und die Kontingente des Hosters im Blick behalten. Liegen die Dateien bereits in der Historie, hilft git lfs migrate – das ist aber ein Umschreiben der Historie mit allen Konsequenzen. Die Arbeit mit der Historie, rebase und weitere fortgeschrittene Git-Werkzeuge üben wir praktisch in unserem Git-Kurs.
Häufige Fragen
Ist Git LFS kostenlos?
Die Erweiterung selbst ist Open Source und kostenlos. Bezahlen müssen Sie gegebenenfalls Speicher und Traffic beim Git-Hoster, wenn Sie die freien Limits Ihres Tarifs überschreiten.
Ab welcher Dateigröße gilt eine Datei für LFS als groß?
Eine feste Grenze gibt es nicht; meist landen Binärdateien ab einigen Megabyte, die sich oft ändern, in LFS. Auch große Textdateien speichert Git ohne LFS effizient.
Kann ich Git LFS wieder aufgeben und die Dateien ins normale Git zurückholen?
Ja, mit git lfs migrate export --include="*.psd" --everything, das die Historie zurückschreibt. Danach entfernen Sie die Regeln aus .gitattributes und machen einen Force-Push.
Funktioniert git diff für Dateien in LFS?
Git zeigt die Änderung des Pointers, nicht des Inhalts, weil die Dateien binär sind. Bilder und Dokumente vergleicht man mit externen Werkzeugen.
Braucht jedes Teammitglied LFS?
Ja, sonst hat ein Mitglied ohne die Erweiterung Pointer statt Dateien in der Arbeitskopie, und seine Commits können große Dateien versehentlich an LFS vorbei hinzufügen.
Dieses Thema wird im Kurs „Git vom Anfänger zum versierten Entwickler“ ausführlich mit Praxis behandelt.
Zum Kurs