Das Problem mit großen Dateien in Git
Traditionell haben sich bestimmte Unternehmen und Institutionen aufgrund der Ineffizienz bei der Handhabung großer Binärdateien von Git ferngehalten. Videospielentwickler und Medienunternehmen müssen sich mit komplexen Texturen, Full-Motion-Videos und hochwertigen Audiodateien auseinandersetzen. Forschungsinstitute müssen große Datensätze im Auge behalten, die Gigabyte oder Terabyte groß sein können. Git hat Schwierigkeiten, diese großen Dateien zu verwalten.
Um das Problem zu verstehen, müssen wir uns ansehen, wie Git Dateien verfolgtt. Immer wenn ein Commit stattfindet, erstellt Git einen Objektknoten mit einem Zeiger auf seinen Elternteil oder mehrere Eltern. Das Git-Datenmodell ist als gerichteter azyklischer Graph (DAG) bekannt. Das DAG-Modell stellt sicher, dass die Eltern-Kind-Beziehung niemals Zyklen bilden kann.
Wir können das Innenleben des DAG-Modells untersuchen. Hier ist ein Beispiel für drei Commits in einem Repository:
$ git log --oneline2beb263 Commit C: Bild hinzugefügt1.jpeg
866178e Commit B: b . hinzufügen.TXT
d48dd8b Commit A: a . hinzufügen.TXT
In Commit A und B haben wir die Textdatei a . hinzugefügt.txt und b.TXT. Dann haben wir in Commit C eine Bilddatei namens image1 hinzugefügt.jpeg. Wir können uns den DAG wie folgt vorstellen:
Commit C Commit B Commit A2beb263 --> 866178e --> d48dd8b
Wenn wir den letzten Commit mit dem folgenden Befehl überprüfen:
$ git cat-file -p 2beb263Baum 7cc17ba5b041fb227b9ab5534d81bd836183a4e3
Elternteil 866178e37df64d9f19fa77c00d5ba9d3d4fc68f5
Autor Zak H
Committer Zak H
Commit C: Bild hinzugefügt1.jpeg
Wir können sehen, dass Commit C (2beb263) Commit B (866178e) als Eltern hat. Wenn wir nun das Baumobjekt von Commit C (7cc17ba) untersuchen, können wir die Blobs (binäre große Objekte) sehen:
$ git cat-file -p 7cc17ba100644 Blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a.TXT
100644 Blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 b.TXT
100644 Blob a44a66f9e06a8faf324d3ff3e11c9fa6966bfb56 image1.jpeg
Wir können die Größe des Bild-Blobs überprüfen:
$ git cat-file -s a44a66f9e871680
Git verfolgt die Änderungen in dieser Baumstruktur. Lassen Sie uns eine Änderung am Bild vornehmen1.jpeg und überprüfen Sie den Verlauf:
$ git log --oneline2e257db Commit D: modifiziertes Bild1.jpeg
2beb263 Commit C: Bild hinzugefügt1.jpeg
866178e Commit B: b . hinzufügen.TXT
d48dd8b Commit A: a . hinzufügen.TXT
Wenn wir das Commit D-Objekt (2e257db) überprüfen:
$ git cat-file -p 2e257dbBaum 2405fad67610acf0f57b87af36f535c1f4f9ed0d
Elternteil 2beb263523725e1e8f9d96083140a4a5cd30b651
Autor Zak H
Committer Zak H
Commit D: geändertes Bild1.jpeg
Und der Baum (2405fad) darin:
$ git cat-file -p 2405fad100644 Blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a.TXT
100644 Blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 b.TXT
100644 Blob cb4a0b67280a92412a81c60df36a15150e713095 image1.jpeg
Beachten Sie, dass der SHA-1-Hash für image1.jpeg hat sich geändert. Es bedeutet, dass ein neuer Blob für image1 erstellt wurde.jpeg. Wir können die Größe des neuen Blobs überprüfen:
$ git cat-file -s cb4a0b61063696
So können Sie die obige DAG-Struktur visualisieren:
Commit D Commit C Commit B Commit A| | | |
2e257db --> 2beb263 --> 866178e --> d48dd8b
| | | |
Baum4 Baum3 Baum2 Baum1
| | | |
Blobs Blobs Blobs Blobs
Jedes Commit-Objekt unterhält seinen eigenen Baum. Blobs werden in diesem Baum gehalten maintained. Git optimiert den Speicherplatz, indem es sicherstellt, dass nur die Unterschiede gespeichert werden und Komprimierung zum Speichern verwendet wird. Aber für binäre Dateiänderungen muss Git ganze Dateien in den Blobs speichern, da es schwierig ist, die Unterschiede zu bestimmen. Auch Bild-, Video- und Audiodateien sind bereits komprimiert. Als Ergebnis endet der Baum für jede Instanz einer modifizierten Binärdatei mit einem großen Blob.
Stellen wir uns ein Beispiel vor, bei dem wir mehrere Änderungen an einer 100-MB-Bilddatei vornehmen.
Commit C --> Commit B --> Commit A| | |
Baum3 Baum2 Baum1
| | |
Blob3 Blob2 Blob1
300 MB 200 MB 100 MB
Jedes Mal, wenn wir die Datei ändern, muss Git einen 100 MB großen Blob erstellen create. Das Git-Repository ist also erst nach 3 Commits 300 MB groß. Sie können sehen, dass die Größe des Git-Repositorys schnell explodieren kann. Da Git eine verteilte Versionskontrolle ist, werden Sie das gesamte Repository auf Ihre lokale Instanz herunterladen und viel mit Branches arbeiten. So werden die großen Blobs zum Leistungsengpass.
Das Git LFS löst das Problem, indem es die Blobs durch Lightweight Pointer Files (PF) ersetzt und einen Mechanismus erstellt, um die Blobs an anderer Stelle zu speichern store.
Commit C --> Commit B --> Commit A| | |
Baum3 Baum2 Baum1
| | |
PF3 PF2 PF1
Lokal speichert Git die Blobs im Git LFS-Cache und remote im Git LFS-Speicher auf GitHub oder BitBucketuck.
PF1 --> Blob1PF2 --> Blob2
PF3 --> Blob3
Wenn Sie jetzt mit dem Git-Repository arbeiten, werden die leichten PF-Dateien für die Routinevorgänge verwendet. Die Blobs werden nur bei Bedarf abgerufen. Wenn Sie beispielsweise Commit C auschecken, sucht Git LFS den PF3-Zeiger und lädt Blob3 herunter. So wird das Arbeits-Repository schlanker und die Leistung wird besser. Sie müssen sich keine Sorgen um die Zeigerdateien machen. Git LFS wird sie hinter den Kulissen verwalten.
Git LFS installieren und ausführen
Es gab frühere Versuche, das Git-Problem mit großen Dateien zu lösen. Aber Git LFS ist gelungen, weil es einfach zu bedienen ist. Sie müssen nur LFS installieren und ihm mitteilen, welche Dateien verfolgt werden sollen.
Sie können Git LFS mit den folgenden Befehlen installieren:
$ sudo apt-get install software-properties-common$ curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sch | sudo bash
$ sudo apt-get install git-lfs
$ git lfs installieren
Nachdem Sie Git LFS installiert haben, können Sie die gewünschten Dateien verfolgen:
$ git lfs track "*.JPEG"Verfolgung "*.JPEG"
Die Ausgabe zeigt Ihnen, dass Git LFS die JPEG-Dateien verfolgt. Wenn Sie mit dem Tracking mit LFS beginnen, finden Sie a .gitattributes-Datei, die einen Eintrag enthält, der die verfolgten Dateien anzeigt. Das .gitattributes-Datei verwendet dieselbe Notation wie .gitignore-Datei. So wird der Inhalt von .gitattributes sieht aus:
$ Katze .gittributes*.jpeg filter=lfs diff=lfs merge=lfs -text
Sie können auch mit dem folgenden Befehl herausfinden, welche Dateien verfolgt werden:
$ git lfs trackAuflisten von verfolgten Mustern
*.jpeg (.Gittribute)
Wenn Sie die Verfolgung einer Datei beenden möchten, können Sie den folgenden Befehl verwenden:
$ git lfs untrack "*.JPEG"Untracking "*.JPEG"
Für allgemeine Git-Operationen müssen Sie sich nicht um LFS kümmern. Es kümmert sich automatisch um alle Backend-Aufgaben. Nachdem Sie Git LFS eingerichtet haben, können Sie wie jedes andere Projekt am Repository arbeiten.
Weiteres Studium
Weitere Informationen zu weiterführenden Themen finden Sie in den folgenden Ressourcen:
- Git LFS-Repository zwischen Hosts verschieben
- Lokale Git LFS-Dateien löschen
- Entfernen von entfernten Git-LFS-Dateien vom Server
- Git LFS-Website
- Git LFS-Dokumentation
Verweise:
- git-lfs.github.com: GitHub-Repository
- github.com/git-lfs/git-lfs/tree/master/docs: GitHub-Dokumentation für Git LFS
- Atlassianer.com/git/tutorials/git-lfs: Atlassian-Tutorials
- Youtube.com: Was ist Git LFS?
- Youtube.com: Tracking riesiger Dateien mit Git LFS von Tim Pettersen, Atlassian
- Youtube.com: Verwalten riesiger Dateien auf dem richtigen Speicher mit Git LFS, YouTube
- Youtube.com: Git Large File Storage - So arbeiten Sie mit großen Dateien, YouTube
- askubuntu.com/questions/799341: How-to-install-git-lfs-on-ubuntu-16-04
- github.com/git-lfs/git-lfs/blob/master/INSTALLIEREN.md: Installationsanleitung