Git LFS (Large File Storage)
Lerne Git LFS (Large File Storage), um große Binärdateien aus dem Repository-Verlauf auszulagern. Einrichtung und Befehle inklusive.
Was ist Git LFS
Git LFS (Large File Storage) ist eine quelloffene Git-Erweiterung, die große Binärdateien — Videos, Datensätze, Design-Assets, Spielgrafiken — aus dem Git-Verlauf heraushalten. Anstatt eine 500-MB-Datei im Repository zu speichern, hinterlegt Git LFS einen winzigen Text-Pointer und bewahrt den eigentlichen Inhalt in einem separaten LFS-Speicher auf. Das Ergebnis: Clones bleiben schnell und das Repository bleibt klein, auch wenn das Projekt Gigabytes an Assets enthält.
Dieses Kapitel behandelt, wann LFS sinnvoll ist, wie man es installiert und Dateien trackt, was ein Pointer tatsächlich enthält, die alltäglichen Befehle, Dateisperrung für nicht zusammenführbare Binärdateien sowie häufige Fallstricke.
Warum große Dateien Git schaden
Git ist für Text ausgelegt und speichert die vollständige Historie jeder Datei. Zudem speichert es Dateien nach Inhalt: Wenn sich eine Binärdatei ändert, bewahrt Git in der Regel die gesamte neue Kopie auf statt eines kleinen Diffs, weil Binärdateien sich nicht sauber differenzieren lassen. Wird eine große Binärdatei mehrfach committet, muss jeder Clone jede Version davon für immer herunterladen — auch Versionen, die niemand braucht. Die Historie bläht sich auf, Clones werden langsam, und Pushes laufen in Timeouts. Git LFS umgeht das Problem, indem es statt des schweren Inhalts nur einen kleinen Pointer versioniert.
Setze LFS ein, wenn Dateien groß und veränderlich sind — Design-Quellen, kompilierte Assets, Datensätze, Audio und Video. Für Dateien, die nie versioniert werden müssen, halte sie mit .gitignore komplett aus dem Repository heraus.
Einrichtung
Installiere zuerst Git selbst, dann die LFS-Erweiterung. Auf den meisten Systemen wird Git LFS separat ausgeliefert (brew install git-lfs, apt install git-lfs oder das Installationsprogramm von git-lfs.com). Aktiviere es einmal pro Rechner:
git lfs installUpdated Git hooks.
Git LFS initialized.Teile LFS mit, welche Dateien verwaltet werden sollen, indem du Muster trackst. Dabei werden Regeln in .gitattributes geschrieben:
git lfs track "*.psd"
git lfs track "*.mp4"
git add .gitattributes.gitattributes sollte committet werden, damit alle Mitarbeitenden dieselben Regeln erhalten. Ab sofort werden passende Dateien automatisch über LFS gespeichert. Committe und pushe wie gewohnt:
git add design.psd
git commit -m "Add hero design source"
git pushGit lädt den Pointer ins Repository hoch und den Binärinhalt in den LFS-Speicher. Bei einem neuen Clone bindet sich Git LFS automatisch ein und lädt den eigentlichen Inhalt für den ausgecheckten Commit herunter.
Wie ein Pointer aussieht
Im Repository wird die getracked Datei durch einen kleinen Text-Pointer ersetzt, der den Inhalts-Hash und die Größe festhält:
version https://git-lfs.github.com/spec/v1
oid sha256:9af1c2a3b4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f7
size 471859200Die drei Zeilen enthalten die Spezifikationsversion, die SHA-256-Objekt-ID des Inhalts (oid) und die Dateigröße in Bytes. Das ist der gesamte Fußabdruck im Git-Verlauf — ein paar hundert Bytes, unabhängig davon, wie groß das Asset ist. Wenn jemand die Datei auscheckt, nutzt Git LFS diesen Pointer, um den eigentlichen Inhalt bei Bedarf abzurufen.
Häufige Befehle
| Befehl | Beschreibung |
|---|---|
git lfs install | Aktiviert LFS für deinen Benutzer (einmalig ausführen). |
git lfs track "<pattern>" | Beginnt, Dateien, die einem Muster entsprechen, über LFS zu verwalten. |
git lfs untrack "<pattern>" | Beendet die Verwaltung eines Musters. |
git lfs ls-files | Listet die derzeit von LFS getrackten Dateien auf. |
git lfs status | Zeigt, welche LFS-Dateien gestaged oder geändert sind. |
git lfs pull | Lädt den LFS-Inhalt für das aktuelle Checkout herunter. |
git lfs fetch | Lädt LFS-Objekte herunter, ohne den Arbeitsbaum zu aktualisieren. |
git lfs prune | Löscht alte, nicht referenzierte LFS-Dateien aus dem lokalen Speicher. |
git lfs migrate | Schreibt vorhandene Historie um, um große Dateien in LFS zu verschieben. |
Um zu überprüfen, was LFS tatsächlich verwaltet, liste die getrackten Dateien auf:
git lfs ls-files9af1c2a3b4 * design.psd
1c0ffee5d6 * intro.mp4Jede Zeile zeigt die kurze Objekt-ID, ein * wenn der eigentliche Inhalt lokal vorhanden ist (- wenn nur der Pointer ausgecheckt ist), und den Pfad.
Dateisperrung
Binärdateien wie .psd oder .fbx lassen sich nicht zusammenführen — wenn zwei Personen dieselbe Datei bearbeiten, gehen die Änderungen einer Person verloren. Git LFS bietet Dateisperrung, damit ein Teammitglied eine Datei vor der Bearbeitung reservieren kann:
git lfs lock images/banner.psd
git lfs locks
git lfs unlock images/banner.psdMarkiere ein Muster in .gitattributes als sperrbar, um es bis zur Sperrung schreibgeschützt zu machen und versehentliche Bearbeitungen zu verhindern:
git lfs track "*.psd" --lockableDateisperrung erfordert Server-Unterstützung (GitHub und GitLab bieten diese).
Vorhandene Dateien in LFS verschieben
Das Tracking wirkt nur auf Dateien, die nach dem Hinzufügen der Regel committet werden. Dateien, die bereits im Verlauf vorhanden sind, bleiben als vollständige Binärdateien in Git. Um sie zu verschieben, schreibe die Historie mit git lfs migrate um:
git lfs migrate import --include="*.mp4"Dies schreibt Commits um und ändert damit deren Hashes — stimme dich mit deinem Team ab und führe danach einen Force-Push durch, wie bei jeder anderen Verlaufsumschreibung.
Wichtige Hinweise
- Server-Unterstützung ist erforderlich. GitHub, GitLab und Bitbucket bieten alle LFS an, oft mit Speicher- und Bandbreitenkontingenten, die Kosten verursachen können. Ein Repository kann sein LFS-Kontingent überschreiten, auch wenn die Git-Größe selbst klein bleibt.
- Alle benötigen die Erweiterung. Wer das Repository clont, muss Git LFS installiert haben, sonst sieht man den Pointer-Text statt der eigentlichen Datei. Tritt das auf, behebt
git lfs pullnach der LFS-Installation das Problem. - Pointer sind normale Git-Objekte. Branching, Merging und Diffing des Pointers funktionieren normal; LFS tauscht den eigentlichen Inhalt nur beim Auschecken aus.