Ich suche nach Meinungen zum Umgang mit großen Binärdateien, von denen mein Quellcode (Webanwendung) abhängig ist. Wir diskutieren derzeit verschiedene Alternativen:
- Kopieren Sie die Binärdateien von Hand.
- Pro: Ich bin mir nicht sicher.
- Contra: Ich bin stark dagegen, da dies die Wahrscheinlichkeit von Fehlern beim Einrichten einer neuen Site / beim Migrieren der alten Site erhöht. Baut eine weitere Hürde auf.
- Verwalten Sie sie alle mit Git .
- Pro: Entfernt die Möglichkeit, das Kopieren einer wichtigen Datei zu vergessen
- Contra: Bläht das Repository auf und verringert die Flexibilität bei der Verwaltung der Codebasis. Das Auschecken, Klonen usw. dauert eine Weile.
- Separate Repositorys.
- Pro: Das Auschecken / Klonen des Quellcodes ist wie immer schnell und die Bilder werden ordnungsgemäß in ihrem eigenen Repository archiviert.
- Contra: Entfernt die Einfachheit, das einzige Git-Repository im Projekt zu haben. Es werden sicherlich einige andere Dinge vorgestellt, über die ich nicht nachgedacht habe.
Was sind deine Erfahrungen / Gedanken dazu?
Außerdem: Hat jemand Erfahrung mit mehreren Git-Repositorys und deren Verwaltung in einem Projekt?
Die Dateien sind Bilder für ein Programm, das PDFs mit diesen Dateien generiert. Die Dateien ändern sich nicht sehr oft (wie in Jahren), sind aber für ein Programm sehr relevant. Das Programm funktioniert nicht ohne die Dateien.
Antworten:
Wenn das Programm ohne die Dateien nicht funktioniert, scheint es eine schlechte Idee zu sein, sie in ein separates Repo aufzuteilen. Wir haben große Testsuiten, die wir in ein separates Repo aufteilen, aber das sind wirklich "Hilfs" -Dateien.
Möglicherweise können Sie die Dateien jedoch in einem separaten Repo verwalten und dann verwenden
git-submodule
, um sie auf vernünftige Weise in Ihr Projekt zu ziehen. Sie hätten also immer noch den vollständigen Verlauf Ihrer gesamten Quelle, aber nach meinem Verständnis hätten Sie nur die eine relevante Revision Ihres Bild-Submoduls. Die Funktiongit-submodule
soll Ihnen helfen, die richtige Version des Codes mit der richtigen Version der Bilder in Einklang zu bringen.Hier ist eine gute Einführung in Submodule aus Git Book.
quelle
Ich habe kürzlich den Git-Anhang entdeckt, den ich großartig finde. Es wurde entwickelt, um große Dateien effizient zu verwalten. Ich benutze es für meine Foto- / Musiksammlungen (usw.). Die Entwicklung des Git-Anhangs ist sehr aktiv. Der Inhalt der Dateien kann aus dem Git-Repository entfernt werden, nur die Baumhierarchie wird von Git verfolgt (über Symlinks). Um jedoch den Inhalt der Datei zu erhalten, ist nach dem Ziehen / Drücken ein zweiter Schritt erforderlich, z.
Es stehen viele Befehle zur Verfügung und es gibt eine großartige Dokumentation auf der Website. Ein Paket ist auf Debian verfügbar .
quelle
git annex
auch unter Windows verfügbar ist . Wenn jemand es jemals in Windows getestet hat, würde ich gerne etwas über seine Erfahrungen erfahren!Eine weitere Lösung ist seit April 2015 Git Large File Storage (LFS) (von GitHub).
Es verwendet git-lfs (siehe git-lfs.github.com ) und wird mit einem Server getestet, der dies unterstützt: lfs-test-server :
Sie können Metadaten nur im Git-Repo und in der großen Datei an anderer Stelle speichern.
quelle
lfs-test-server
wird als nicht für die Produktion bestimmt erklärt. Eigentlich arbeite ich am Produktions-LFS-Server ( github.com/artemkin/git-lfs-server ). Es ist in Bearbeitung, aber bereits wartbar, und wir testen es intern.Schauen Sie sich git bup an , eine Git-Erweiterung zum intelligenten Speichern großer Binärdateien in einem Git-Repository.
Sie möchten es als Submodul haben, müssen sich aber keine Sorgen machen, dass das Repository schwer zu handhaben ist. Einer ihrer Anwendungsbeispiele ist das Speichern von VM-Images in Git.
Ich habe eigentlich keine besseren Komprimierungsraten gesehen, aber meine Repositorys enthalten keine wirklich großen Binärdateien.
Ihr Kilometerstand kann variieren.
quelle
Sie können auch Git-Fett verwenden . Ich mag, dass es nur auf Lager Python und hängt
rsync
. Es unterstützt auch den üblichen Git-Workflow mit den folgenden selbsterklärenden Befehlen:Darüber hinaus müssen Sie eine Gitfat-Datei in Ihr Repository einchecken und Ihre Gitattributes ändern, um die Dateierweiterungen anzugeben, die Sie verwalten möchten
git fat
.Sie fügen eine Binärdatei mit der Normalen hinzu
git add
, die wiederumgit fat
basierend auf Ihren Gitattributes-Regeln aufgerufen wird.Schließlich hat es den Vorteil, dass der Speicherort Ihrer Binärdateien von Repositorys und Benutzern gemeinsam genutzt werden kann und alles unterstützt
rsync
tut.UPDATE: Verwenden Sie kein Git-Fat, wenn Sie eine Git-SVN-Bridge verwenden. Am Ende werden die Binärdateien aus Ihrem Subversion-Repository entfernt. Wenn Sie jedoch ein reines Git-Repository verwenden, funktioniert es hervorragend.
quelle
Ich würde Submodule (als Pat Notz) oder zwei verschiedene Repositories verwenden. Wenn Sie Ihre Binärdateien zu oft ändern, würde ich versuchen, die Auswirkungen des riesigen Repositorys zu minimieren, das den Verlauf bereinigt:
Ich hatte vor einigen Monaten ein sehr ähnliches Problem: ~ 21 GB MP3-Dateien, nicht klassifiziert (schlechte Namen, schlechte ID3s, weiß nicht, ob mir diese MP3-Datei gefällt oder nicht ...) und auf drei Computern repliziert.
Ich habe ein externes Festplattenlaufwerk mit dem Haupt-Git-Repository verwendet und es in jeden Computer geklont. Dann fing ich an, sie auf die gewohnte Weise zu klassifizieren (drücken, ziehen, zusammenführen ... viele Male löschen und umbenennen).
Am Ende hatte ich nur ~ 6 GB MP3-Dateien und ~ 83 GB im .git-Verzeichnis. Ich habe
git-write-tree
und benutztgit-commit-tree
eine neue zu begehen, zu schaffen , ohne Vorfahren zu begehen, und begann zu , dass eine neue Niederlassung Zeige begehen. Das "Git-Protokoll" für diesen Zweig zeigte nur ein Commit.Dann habe ich den alten Zweig gelöscht, nur den neuen Zweig beibehalten, die Ref-Protokolle gelöscht und "git prune" ausgeführt: Danach haben meine .git-Ordner nur noch ~ 6 GB gewichtet ...
Sie können das riesige Repository von Zeit zu Zeit auf die gleiche Weise "bereinigen": Ihre "Git-Klone" werden schneller sein.
quelle
Die Lösung, die ich vorschlagen möchte, basiert auf verwaisten Zweigen und einem leichten Missbrauch des Tag-Mechanismus, der im Folgenden als * Orphan Tags Binary Storage (OTABS) bezeichnet wird.
TL; DR 12-01-2017 Wenn Sie Githubs LFS oder einen anderen Drittanbieter verwenden können, sollten Sie dies auf jeden Fall tun. Wenn Sie nicht können, dann lesen Sie weiter. Seien Sie gewarnt, diese Lösung ist ein Hack und sollte als solche behandelt werden.
Wünschenswerte Eigenschaften von OTABS
git pull
undgit fetch
einschließlichgit fetch --all
sind immer noch bandbreiteneffizient , dh nicht alle großen Binärdateien werden standardmäßig von der Fernbedienung abgerufen.Unerwünschte Eigenschaften von OTABS
git clone
möglicherweise ineffizient (aber nicht unbedingt, abhängig von Ihrer Verwendung). Wenn Sie diese Lösung bereitstellen, müssen Sie möglicherweise Ihren Kollegen raten, siegit clone -b master --single-branch <url>
anstelle von zu verwendengit clone
. Dies liegt daran, dass git clone standardmäßig buchstäblich das gesamte Repository klont, einschließlich Dinge, für die Sie normalerweise Ihre Bandbreite nicht verschwenden möchten, wie nicht referenzierte Commits. Entnommen aus SO 4811434 .git fetch <remote> --tags
Bandbreite ineffizient, aber nicht unbedingt den Speicher ineffizient. Sie können Ihren Kollegen jederzeit raten, es nicht zu verwenden.git gc
Trick anwenden, um Ihr Repository von allen Dateien zu bereinigen, die Sie nicht mehr benötigen.Hinzufügen der Binärdateien
Bevor Sie beginnen, stellen Sie sicher, dass Sie alle Ihre Änderungen festgeschrieben haben, Ihr Arbeitsbaum auf dem neuesten Stand ist und Ihr Index keine nicht festgeschriebenen Änderungen enthält. Es kann eine gute Idee sein, alle Ihre lokalen Niederlassungen auf Ihre Fernbedienung (Github usw.) zu übertragen, falls eine Katastrophe eintreten sollte.
git checkout --orphan binaryStuff
wird den Trick machen. Dies erzeugt einen Zweig, der vollständig von jedem anderen Zweig getrennt ist, und das erste Commit, das Sie in diesem Zweig vornehmen, hat kein übergeordnetes Element, wodurch es zu einem Root-Commit wird.git rm --cached * .gitignore
.rm -fr * .gitignore
. Das interne.git
Verzeichnis bleibt unberührt, da der*
Platzhalter nicht mit ihm übereinstimmt.git fetch
ihre Verbindung verstopfen. Sie können dies vermeiden, indem Sie ein Tag anstelle eines Zweigs verschieben. Dies kann sich weiterhin auf die Bandbreite und den Dateisystemspeicher Ihres Kollegen auswirken, wenn dieser die Gewohnheit hat zu tippengit fetch <remote> --tags
, aber zur Problemumgehung weiterlesen. Fahre fort undgit tag 1.0.0bin
git push <remote> 1.0.0bin
.git branch -D binaryStuff
. Ihr Commit wird nicht für die Speicherbereinigung markiert, da ein darauf verwaltetes verwaistes Tag1.0.0bin
ausreicht, um es am Leben zu erhalten.Auschecken der Binärdatei
git checkout 1.0.0bin -- VeryBigBinary.exe
.1.0.0bin
heruntergeladen haben. In diesem Fall müssen Sie diesgit fetch <remote> 1.0.0bin
vorher tun .VeryBigBinary.exe
in die Ihres Masters einfügen.gitignore
, so dass niemand in Ihrem Team versehentlich die Hauptgeschichte des Projekts mit der Binärdatei verschmutzt.Vollständiges Löschen der Binärdatei
Wenn Sie VeryBigBinary.exe vollständig aus Ihrem lokalen Repository, Ihrem Remote-Repository und den Repositorys Ihres Kollegen löschen möchten, können Sie einfach:
git push <remote> :refs/tags/1.0.0bin
git tag -l | xargs git tag -d && git fetch --tags
. Entnommen aus SO 1841341 mit geringfügiger Modifikation.git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
. Außerdem werden alle anderen nicht referenzierten Commits gelöscht. Entnommen aus SO 1904860git clone -b master --single-branch <url>
stattgit clone
.2.0.0bin
. Wenn Sie sich Sorgen machen, dass Ihre Kollegen tippengit fetch <remote> --tags
, können Sie es tatsächlich erneut benennen1.0.0bin
. Dadurch wird sichergestellt, dass beim nächsten Abrufen aller Tags die alten1.0.0bin
nicht referenziert und für die nachfolgende Speicherbereinigung markiert werden (mithilfe von Schritt 3). Wenn Sie versuchen, ein Tag auf der Fernbedienung zu überschreiben, müssen Sie Folgendes verwenden-f
:git push -f <remote> <tagname>
Nachwort
OTABS berührt weder Ihren Master noch andere Quellcode- / Entwicklungszweige. Die Commit-Hashes, die gesamte Historie und die geringe Größe dieser Zweige bleiben davon unberührt. Wenn Sie Ihren Quellcode-Verlauf bereits mit Binärdateien aufgebläht haben, müssen Sie ihn als separate Arbeit bereinigen. Dieses Skript könnte nützlich sein.
Bestätigt, um mit git-bash unter Windows zu arbeiten.
Es ist eine gute Idee, eine Reihe von Standard-Trics anzuwenden , um die Speicherung von Binärdateien effizienter zu gestalten. Durch häufiges Ausführen von
git gc
(ohne zusätzliche Argumente) optimiert git die zugrunde liegende Speicherung Ihrer Dateien mithilfe von Binärdeltas. Wenn es jedoch unwahrscheinlich ist, dass Ihre Dateien von Commit zu Commit ähnlich bleiben, können Sie binäre Deltas vollständig ausschalten. Da es keinen Sinn macht, bereits komprimierte oder verschlüsselte Dateien wie .zip, .jpg oder .crypt zu komprimieren, können Sie mit git die Komprimierung des zugrunde liegenden Speichers deaktivieren. Leider ist dies eine Alles-oder-Nichts-Einstellung, die sich auch auf Ihren Quellcode auswirkt.Möglicherweise möchten Sie Teile von OTABS skripten, um eine schnellere Verwendung zu ermöglichen. Insbesondere das Skripting der Schritte 2-3 vom vollständigen Löschen von Binärdateien in einen
update
Git-Hook kann dem Git-Abruf eine überzeugende, aber möglicherweise gefährliche Semantik verleihen ("Abrufen und Löschen aller veralteten Dateien ").Möglicherweise möchten Sie Schritt 4 des vollständigen Löschens von Binärdateien überspringen , um einen vollständigen Verlauf aller Binäränderungen auf der Fernbedienung auf Kosten des Aufblähens des zentralen Repositorys zu erhalten. Lokale Repositories bleiben im Laufe der Zeit schlank.
In der Java-Welt ist es möglich, diese Lösung mit zu kombinieren
maven --offline
, um einen reproduzierbaren Offline-Build zu erstellen, der vollständig in Ihrer Versionskontrolle gespeichert ist (mit maven ist dies einfacher als mit gradle). In der Golang-Welt ist es möglich, auf dieser Lösung aufzubauen, um stattdessen Ihren GOPATH zu verwaltengo get
. In der Python-Welt ist es möglich, dies mit virtualenv zu kombinieren, um eine eigenständige Entwicklungsumgebung zu erstellen, ohne sich bei jedem Build von Grund auf auf PyPi-Server verlassen zu müssen.Wenn Ihre Binär - Dateien sehr oft ändern, wie Build - Artefakte, könnte es eine gute Idee , um Skript eine Lösung , die speichert 5 neueste Versionen der Artefakte in den Orphan - Tags sein
monday_bin
,tuesday_bin
...,friday_bin
und auch eine Waise Tag für jede Veröffentlichung1.7.8bin
2.0.0bin
usw. Sie können dieweekday_bin
alten Binärdateien täglich drehen und löschen. Auf diese Weise erhalten Sie das Beste aus zwei Welten: Sie behalten den gesamten Verlauf Ihres Quellcodes, aber nur den relevanten Verlauf Ihrer binären Abhängigkeiten. Es ist auch sehr einfach, die Binärdateien für ein bestimmtes Tag abzurufen, ohne den gesamten Quellcode mit seinem gesamten Verlauf abzurufen:git init && git remote add <name> <url> && git fetch <name> <tag>
sollte dies für Sie tun.quelle
git gc
" - hörte genau dort auf zu lesen. Warum sollte jemand seinen letzten Sicherheitsgurt zugunsten eines Hacks aufgeben?git gc
ist nicht unsicher auszuführen. Alle Ihre baumelnden Commits werden standardmäßig mindestens 30 Tage lang sicher auf der Festplatte gespeichertgit push <remote> 1.0.0bin
-remote: error: GH001: Large files detected. You may want to try Git Large File Storage
. Es sieht so aus, als würde GitHub dies nicht mehr unterstützen? Die fragliche Binärdatei hatte eine Größe von 100 MB.Meiner Meinung nach sollten Sie ernsthaft in Betracht ziehen, ein anderes Git-Repository zu verwenden (oder eine andere Möglichkeit, auf diese Dateien zuzugreifen) , wenn Sie diese großen Dateien wahrscheinlich häufig ändern oder wenn Sie beabsichtigen, viele
git clone
odergit checkout
zu erstellen.Wenn Sie jedoch wie wir arbeiten und Ihre Binärdateien nicht häufig geändert werden, ist der erste Klon / Checkout lang, aber danach sollte er so schnell sein, wie Sie möchten (da Ihre Benutzer weiterhin das erste geklonte Repository verwenden, das sie verwenden hätten).
quelle
SVN scheint mit binären Deltas effizienter umzugehen als Git.
Ich musste mich für ein Versionsverwaltungssystem für die Dokumentation entscheiden (JPEG-Dateien, PDF-Dateien und ODT-Dateien). Ich habe gerade getestet, wie man eine JPEG-Datei hinzufügt und viermal um 90 Grad dreht (um die Wirksamkeit von binären Deltas zu überprüfen). Das Repository von Git wuchs um 400%. Das Repository von SVN wuchs nur um 11%.
Es sieht also so aus, als ob SVN mit Binärdateien viel effizienter ist.
Meine Wahl ist also Git für Quellcode und SVN für Binärdateien wie Dokumentation.
quelle
git gc
die Gesamtgröße des Git-Repositorys auf 184 KB reduziert. Dann habe ich ein einzelnes Pixel von Weiß in Schwarz geändert und diese Änderung vorgenommen.git gc
Die Gesamtgröße des Git-Repositorys wurde auf 388 KB erhöht, und nachdem die Größe des gesamten Git-Repositorys auf 184 KB reduziert wurde. Dies zeigt, dass Git ziemlich gut darin ist, Deltas von Binärdateien zu komprimieren und zu finden.git clone --filter
ab Git 2.19 + flache KloneDiese neue Option könnte schließlich die endgültige Lösung für das Problem mit Binärdateien sein, wenn die Entwickler von Git und GitHub sie benutzerfreundlich genug machen (was sie beispielsweise für Submodule wohl noch nicht erreicht haben ).
Es ermöglicht tatsächlich nur das Abrufen von Dateien und Verzeichnissen, die Sie für den Server benötigen, und wurde zusammen mit einer Remote-Protokollerweiterung eingeführt.
Damit könnten wir zuerst einen flachen Klon erstellen und dann automatisieren, welche Blobs mit dem Build-System für jeden Build-Typ abgerufen werden sollen.
Es gibt sogar bereits eine
--filter=blob:limit<size>
, mit der die maximale abzurufende Blob-Größe begrenzt werden kann.Ich habe ein minimal detailliertes Beispiel dafür bereitgestellt, wie die Funktion aussieht: Wie klone ich nur ein Unterverzeichnis eines Git-Repositorys?
quelle
Ich persönlich habe bei einigen meiner Cloud-Hosts Synchronisationsfehler mit Git festgestellt, nachdem die Binärdaten meiner Webanwendungen über der 3-GB-Marke lagen . Ich habe damals über BFT Repo Cleaner nachgedacht , aber es fühlte sich wie ein Hack an. Seitdem habe ich begonnen, Dateien nur außerhalb des Git-Bereichs zu halten und stattdessen speziell entwickelte Tools wie Amazon S3 für die Verwaltung, Versionierung und Sicherung von Dateien zu nutzen.
Ja. Hugo-Themen werden hauptsächlich auf diese Weise verwaltet. Es ist ein bisschen dick, aber es erledigt den Job.
Mein Vorschlag ist , das richtige Werkzeug für den Job auszuwählen . Wenn es sich um ein Unternehmen handelt und Sie Ihre Codeline auf GitHub verwalten, zahlen Sie das Geld und verwenden Sie Git-LFS. Andernfalls könnten Sie kreativere Optionen wie die dezentrale, verschlüsselte Dateispeicherung mithilfe der Blockchain untersuchen .
Weitere zu berücksichtigende Optionen sind Minio und s3cmd .
quelle
Schauen Sie sich camlistore an . Es ist nicht wirklich Git-basiert, aber ich finde es besser geeignet für das, was Sie tun müssen.
quelle