13 Punkte von GN⁺ 2025-08-16 | 1 Kommentare | Auf WhatsApp teilen
  • Das Git-Projekt hat vor Kurzem offiziell begonnen, das Problem der Verwaltung großer Dateien direkt selbst zu lösen
  • Git LFS ist eine Behelfslösung, die für Nutzer verschiedene Kosten und Vendor-Lock-in mit sich bringt
  • Mit der jüngeren Funktion partial clone kann Git selbst inzwischen den Großteil der Aufgaben von LFS übernehmen
  • Künftig wird mit large object promisor zudem eine neue Lösung zur Integration in offizielles Git vorbereitet
  • Dadurch zeichnet sich ab, dass die endgültige Lösung für die Verwaltung großer Dateien nicht in externen Erweiterungen, sondern in Git selbst liegen wird

Das Problem großer Dateien in Git und der Wandel

  • Wenn Git einen größten Erzfeind hat, dann sind es große Dateien
  • Große Dateien blähen Git-Repositories auf, verlangsamen git clone und wirken sich auch in den meisten Hosting-Umgebungen negativ aus

Das Erscheinen von Git LFS und seine Grenzen

  • 2015 veröffentlichte GitHub Git LFS, um das Problem großer Dateien zu umgehen
  • Doch Git LFS selbst bringt zusätzliche Komplexität und Speicherkosten mit sich
  • Die Git-Community hat stillschweigend über das Grundproblem großer Dateien nachgedacht, und in den jüngsten offiziellen Releases von Git wurde eine neue Richtung für die Verwaltung großer Dateien ohne LFS aufgezeigt

Was schon heute möglich ist: Git LFS durch partial clone ersetzen

  • Das Prinzip von partial clone

    • Git LFS: Große Dateien werden außerhalb des Repositories abgelegt, und für die Arbeit werden nur die benötigten Dateien heruntergeladen
    • Git partial clone (eingeführt 2017):
      • Mit der Option --filter wird geklont, wobei Blobs ab einer gewünschten Größe ausgeschlossen werden
      • Die jeweiligen großen Dateien werden nur bei Bedarf vom Server nachgeladen

      Mit Partial Clone müssen [große binäre Assets] während Clone und Fetch nicht vorab heruntergeladen werden, wodurch Download-Zeit und Speicherplatzbedarf sinken

  • Gemeinsamkeiten von partial clone und LFS

    • 1. Minimale Checkout-Größe: Nur die neueste Version wird bezogen, die vollständige Dateihistorie wird ausgelassen
    • 2. Schnelles Klonen: Da keine großen Dateien übertragen werden, ist clone schneller
    • 3. Schnelles Setup: Anders als bei shallow clone bleibt Zugriff auf die gesamte Projekthistorie möglich
  • Beispiel für den Einsatz von partial clone

    • Ein Beispiel für Klon-Geschwindigkeit und Speicherverbrauch bei einem Repository mit viel Historie großer PNG-Dateien:
      • Normales Klonen dauert fast 4 Minuten und belegt 1,3 GB
      • Mit partial clone und einem Blob-Limit von 100 KB ist das Repository in 6 Sekunden geklont und belegt 49 MB
      • Gegenüber dem Original verbessert sich die Klon-Geschwindigkeit um 97 %, die Checkout-Größe sinkt um 96 %
  • Grenzen von partial clone

    • Wenn gefilterte Daten benötigt werden (z. B. git diff, git blame, git checkout), fordert Git die Datei vom Server an
    • Das ist dieselbe Eigenschaft wie bei Git LFS
    • In der Praxis ist es selten, dass man für Binärdateien blame ausführen muss

Probleme von Git LFS

  • Starker Vendor-Lock-in: Die GitHub-Implementierung unterstützt nur eigene Server und führt zu Gebühren sowie Abhängigkeiten
  • Kostenproblem: Für 50 GB Speicher kostet GitHub LFS 40 US-Dollar pro Jahr, Amazon S3 13 US-Dollar
  • Schwer rückgängig zu machen: Nach einer Umstellung auf LFS ist eine Rückkehr ohne Umschreiben der Historie nicht möglich
  • Fortlaufender Setup-Aufwand: Alle Beteiligten müssen LFS installieren; fehlt die Installation, erscheinen statt Dateien nur Metadaten-Dateien, was Verwirrung stiftet

Ausblick: Large Object Promisor

  • Große Dateien verursachen auch auf Hosting-Plattformen wie GitHub und GitLab Kostenprobleme
  • Git LFS senkt Serverkosten, indem große Dateien auf ein CDN ausgelagert werden
  • Was ist Large Object Promisor?

    • Anfang dieses Jahres hat Git eine Funktion namens large object promisor offiziell gemergt
    • Diese Funktion reduziert ähnlich wie LFS die Speicherlast auf Serverseite, verringert aber die Komplexität für Nutzer deutlich

      Diese Arbeit zielt darauf ab, serverseitige Vorgänge zu verbessern, insbesondere bei bereits binär komprimierten großen Blobs
      Es handelt sich um eine Lösung als Alternative zu Git LFS
      Large Object Promisors, git-scm.com

  • Funktionsweise

    • 1. Nutzer pushen große Dateien zu einem Git-Host
    • 2. Der Host lagert große Dateien an ein Backend-Promisor aus
    • 3. Beim Klonen liefert der Git-Host dem Client Informationen über den Promisor
    • 4. Der Client lädt die großen Dateien bei Bedarf automatisch von diesem Promisor herunter
  • Aktueller Stand und Herausforderungen

    • Der Large Object Promisor befindet sich noch in Entwicklung; im März 2025 wurde ein Teil des Codes in Git gemergt
    • In GitLab und anderswo laufen zusätzliche Implementierungen und Diskussionen zu offenen Problemen
    • Bis zur breiten Einführung wird es noch Zeit brauchen
    • Vorerst bleibt die Abhängigkeit von Git LFS für die Speicherung großer Dateien unvermeidlich
    • Sobald sich der Promisor verbreitet, dürfte auch auf GitHub das Hochladen von Dateien über 100 MB möglich werden

Fazit: Die Zukunft großer Dateien in Git ist Git

  • Das Git-Projekt beschäftigt sich stellvertretend für euch fortlaufend mit dem Problem großer Dateien
  • Derzeit ist Git LFS weiterhin notwendig
  • Doch mit der Weiterentwicklung von partial clone und large object promisors wird Git LFS nach und nach überflüssig, und bald dürfte eine Zeit kommen, in der sich große Dateien allein mit Git einfach verwalten lassen
  • In Zukunft wird nur noch die Idee, eine MP3-Bibliothek in Git abzulegen, das letzte Hindernis für den Einsatz großer Dateien sein

1 Kommentare

 
GN⁺ 2025-08-16
Hacker-News-Kommentar
  • Selbst das alte svn funktionierte problemlos mit einem 150-GB-Arbeitsverzeichnis voller großer Binärdateien, während git das nicht tut. Ich frage mich, warum svn bei großen Binärdateien einen anderen Ansatz verfolgt als git und ob git nicht dasselbe tun könnte. Außerdem ist Dateisperren eine essenzielle Funktion beim Umgang mit Binärdaten: Nur eine Person sollte an einer bestimmten Datei arbeiten können, während alle anderen nur Lesezugriff haben, um verwirrende Merge-Probleme zu vermeiden. Ich verstehe auch nicht so recht, ob das Auslagern großer Dateien nach extern tatsächliche Performance- oder Stabilitätsprobleme verbessert. Am Ende ist es nur ein anderes Repository, aber ein Repository bleibt ein Repository. Dieses Offloading wirkt letztlich wie eine Methode, mit der öffentliche git-Foren die Speicherkosten großer Dateien vermeiden wollen

    • git und svn sind komplett unterschiedlich aufgebaut. git ist vollständig dezentralisiert, daher muss jedes Repository die komplette Historie aller Dateien enthalten, und das Konzept von Sperren ist dort bedeutungslos. Man sollte einfach das Versionskontrollsystem wählen, das zum Projekt passt; git muss kein Alleskönner sein
  • Das Konzept der Large Object Promisors gefällt mir. Wenn man so etwas einfach an S3 anschließen könnte, würde ich wahrscheinlich sofort von bestehendem LFS umsteigen. S3 hat starke Synergien bei der Versionsverwaltung großer Binärdateien. Ein Vorteil ist auch Intelligent Tiering, bei dem Daten automatisch in günstigere Storage-Tiers verschoben werden, je älter sie werden. Wenn die Wiederherstellung von 10 Jahre alten Daten einen halben Tag dauert, ist das für mich in Ordnung

    • Sehe ich genauso. Ich verstehe nicht, warum das nicht von Anfang an der Standardansatz war. Ich betreibe selbst einen kleinen git-LFS-Server, und wenn git S3 nativ unterstützen würde, wäre ich sofort bereit zu wechseln

    • Bei meinem aktuellen Arbeitgeber cachen wir LFS-Objekte zur Kostensenkung in einem Bucket. Bei jedem PR-Lauf holen wir mit git lfs ls-files die Dateiliste, laden sie aus GCP, speichern die Objekte lokal mit git lfs checkout und holen per Pull nur die fehlenden nach. Nicht gecachte Dateien laden wir anschließend mit gcloud storage rsync wieder in den Bucket hoch. Für Entwickler ist keine zusätzliche Konfiguration nötig; sie müssen nur neue Objekte pullen, und auch die GitHub-UI zeigt den Repository-Zustand weiterhin korrekt an. Früher hatten wir überlegt, selbst ein LFS-Backend aufzusetzen, aber diese Methode löst unser aktuell größtes Problem. GitHub verlangte zu viel Traffic-Gebühr, wenn LFS-Dateien in CI heruntergeladen wurden, und wegen des 10-GB-Cache-Limits sowie der fehlenden Teilbarkeit zwischen Branches mussten wir sie jedes Mal erneut herunterladen. Ich hätte die Cache-Größe sogar gegen Bezahlung gern erhöht, aber diese Möglichkeit gab es nicht. Um das für Entwickler auszurollen, muss man im Grunde nur einen git-Hook hinzufügen

    • Ist S3 ein Amazon-Dienst?

  • Es werden zwar mehrere Nachteile von Git LFS genannt, aber ich stimme nicht zu, dass es einen Vendor Lock-in gibt. GitHub stellt einen offenen Client und Server bereit, daher ist diese Behauptung unfair. Allerdings funktioniert LFS nicht bei Offline- oder Sneakernet-Arbeit; das ist zwar kein häufiger Fall, aber erwähnenswert. Large Object Promisors scheinen die clientseitige Komplexität von LFS auf den Server zu verlagern, also letztlich nur die Stelle der Komplexität zu ändern. Wenn der git-Server Dateien an einen LFS-Server und einen Objektspeicher hochlädt, bringt das andere Trade-offs mit sich. Ich frage mich, was passiert, wenn öffentliche git-Server beim Hochladen Promisor-Remotes verbergen

    • Ich finde LFS wirklich nicht besonders gut. Auch die Server-Implementierung ist chaotisch, und Objektinhalt und Speicherverfahren sind miteinander vermischt. Auch das Opt-in-Verfahren ist miserabel: Wenn man es gedankenlos benutzt, bekommt man nur kleine Textdateien statt der eigentlichen gewünschten Dateien. Ob die neue Lösung besser ist, weiß ich nicht, aber dass LFS nicht gut ist, scheint klar zu sein

    • Ein weiteres Problem mit Git LFS, das ich kürzlich gelernt habe, ist, dass bei Migrationen sogar die .gitattributes der Vorfahren-Commits verunreinigt werden. Wenn also in der Commit-Folge A→B→C erst in C eine große Datei zu LFS hinzugefügt wurde, bekommen auch A und B eine .gitattributes, die auf nicht existierende LFS-Dateien verweist. Während der Migration wird .gitattributes rückwärts durch die Historie propagiert, weil nicht geprüft wird, ob das konkrete Objekt im aktuellen Commit überhaupt existiert

    • Früher unterstützte Git LFS kein SSH, sodass man zwingend ein SSL-Zertifikat haben musste. Das war für Leute, die zu Hause selbst hosten, eine echte Einstiegshürde. GitLab scheint kürzlich einen Patch für SSH-Unterstützung eingebaut zu haben

  • In meinem Software-Engineering-Kurs wurde empfohlen, große Dateien wie Medien nicht in Git zu speichern, sondern in einem Artifact-Repository wie Artifactory. Dann kann man sie in Form von Snapshot-Abhängigkeiten ausliefern, und das Build-System holt automatisch nur die neueste Version. Alte lokal angesammelte Dateien bei Kolleginnen und Kollegen lassen sich dann einfach bereinigen, indem man nur den Build-System-Cache leert

    • Das wirkt ein bisschen wie eine Art git-Submodul. Wenn das Problem damit lösbar wäre, hätten die Leute es wahrscheinlich längst so gemacht. git-Submodule unterstützen auch flache Klone (passender Link: https://stackoverflow.com/questions/2144406/how-to-make-shallow-git-submodules). Ich hatte selbst noch nie mit Problemen rund um große Dateien zu tun, daher würde mich interessieren, warum dieser Ansatz nicht funktioniert. Die auf SO genannten Nachteile wirken auf mich nicht so gravierend

    • Ich frage mich, ob im Unterricht auch die Architektur von CI/CD-Systemen behandelt wird. Viele Berufsanfänger sind heute nicht mit der Gesamtarchitektur vertraut, in der GitLab, Artifactory, CodeSonar, Anchore und Ähnliches zusammenspielen

    • Auch dieser Ansatz hat Nachteile. CI/CD-Systeme oder Entwickler benötigen zusätzliche Zugangsdaten. Commits werden mehrstufiger, und man muss zuerst die Artifact-ID kennen. Wenn man versucht, das mit git-Hooks zu automatisieren, landet man am Ende wieder bei einer Komplexität ähnlich wie bei git-lfs

  • Dieser Artikel bewertet LFS unfair. LFS ist nicht an GitHub gebunden, und auch das Protokoll ist offen. Die Nachteile von LFS sind als git-Erweiterung kaum vermeidbar, und Promisors sind im Grunde ebenfalls dasselbe Konzept wie LFS. Der Unterschied ist nur, dass es in git selbst eingebaut wurde und dadurch die UX etwas besser ist

    • Ein Repository, das auch nur einmal LFS verwendet hat, ist dauerhaft daran gebunden. Um den belegten Speicherplatz zu reduzieren, muss man das ganze Repository löschen, und das wird offiziell nicht einmal klar kommuniziert. Wir haben das Problem selbst erlebt, als wir für unsere internen GitHub-Statistiken eine große komprimierte DB-Datei in LFS gespeichert hatten
  • Das ist keine echte Lösung. Auch git LFS ist nur ein Provisorium, und selbst wenn man beim Klonen Filterargumente angibt, ist das keine grundlegende Lösung. git clone ist der erste Befehl, den praktisch alle lernen, und dann müsste man sich jedes Mal an zusätzliche Filter erinnern. Wenn man sich vertut, kostet das nur unnötig Zeit, und selbst wenn es klappt, funktioniert das geklonte Repository vielleicht nicht richtig. Eine echte Lösung wäre letztlich ein Wechsel zu einer Struktur, die wie rsync zuerst effizient die aktuellen Dateien holt. git macht solche grundlegenden Änderungen normalerweise nicht

    • Dem stimme ich stark zu. git „löst“ Probleme ständig, indem es noch ein Flag hinzufügt, aber die meisten Nutzer kennen diese Funktionen gar nicht. Wenn man stattdessen die Standardwerte verbessert, könnte man vieles lösen, ohne die Kompatibilität zu brechen

    • das geklonte Repository funktioniert vielleicht nicht richtig
      Tatsächlich fehlt nur die Blob-Historie

    • Wenn rsync das Problem gelöst haben soll: Wie würde das konkret aussehen? Nicht der Algorithmus, sondern was beim Benutzer nach git clone tatsächlich im lokalen Dateisystem landet, würde mich interessieren

    • Wenn der Großteil des Repository-Volumens in alten Revisionen steckt, dann ist ein rsync-artiger Ansatz, bei dem zuerst nur die aktuellste Version geholt wird, für die meisten Nutzer wahrscheinlich die passendste Lösung

  • Ich freue mich sehr darüber, dass Unterstützung für große Dateien in den Git-Core aufgenommen wird. Selbst wenn es eine externe Lösung ist, bleibt die Opt-in-Struktur letztlich ähnlich. Ich wollte die Zahl der Befehle so gering wie möglich halten und alles möglichst nahtlos machen, daher habe ich die API ausschließlich rund um Smudge-/Clean-Filter in der Datei .gitattributes entworfen. Außerdem habe ich direkt mit Atlassian und Microsoft zusammengearbeitet, um Vendor Lock-in zu vermeiden, und beim File-Locking-API kam auch viel Unterstützung von Atlassian. LFS wird als Open Source mit kompatibler Unterstützung durch drei Hosts angeboten

  • Wir entwickeln oxen, um Probleme zu lösen, die wir mit git oder git-lfs hatten. Es folgt derselben git-Oberfläche, arbeitet aber bei großen Dateien und in Monorepo-Umgebungen mit Millionen Dateien deutlich schneller. Wir bieten ein Open-Source-CLI und einen Server an; falls Interesse besteht, freuen wir uns über Feedback
    https://github.com/Oxen-AI/Oxen

  • Auch das Speicherformat von git selbst müsste eigentlich grundlegend überarbeitet werden, etwa hin zu inhaltsbasiertem Chunking für Dateien und Verzeichnisse wie bei modernen Backup-Tools wie restic oder borg

  • Bei den Nachteilen von GitLFS fehlt noch das Authentifizierungsproblem: Wenn man keinen SSH-Agent nutzt, muss man sich selbst für einen einzigen Push mehrfach authentifizieren. Ich habe selbst erlebt, dass das zwei- oder dreimal oder sogar noch öfter nötig war