Die Lösung, die ich vorschlagen möchte, basiert auf verwaisten Zweigen und einem leichten Missbrauch des Tag-Mechanismus, im Folgenden als *Orphan Tags Binary Storage bezeichnet (OTABS)
TL;DR 12-01-2017 Wenn Sie das LFS von Github oder einem anderen Drittanbieter verwenden können, sollten Sie das auf jeden Fall tun. Wenn Sie das nicht können, dann lesen Sie weiter. Seien Sie gewarnt, diese Lösung ist ein Hack und sollte als solcher behandelt werden.
Wünschenswerte Eigenschaften von OTABS
- Es ist ein reiner Git y nur Git Lösung - sie erledigt die Aufgabe ohne Software von Drittanbietern (wie git-annex) oder Infrastruktur von Drittanbietern (wie github's LFS).
- speichert er die Binärdateien effizient d.h. es bläht die Historie Ihres Repositorys nicht auf.
git pull
y git fetch
, einschließlich git fetch --all
sind noch bandbreiteneffizient d.h. nicht alle großen Binärdateien werden standardmäßig von der Gegenstelle bezogen.
- es funktioniert bei Windows .
- es speichert alles in einem einzelnes Git-Repository .
- Sie ermöglicht es Löschung von veralteten Binärdateien (im Gegensatz zu bup).
Unerwünschte Eigenschaften von OTABS
- es macht
git clone
potenziell ineffizient (aber nicht unbedingt, je nach Nutzung). Wenn Sie diese Lösung einsetzen, müssen Sie Ihren Kollegen möglicherweise raten, Folgendes zu verwenden git clone -b master --single-branch <url>
anstelle von git clone
. Das liegt daran, dass git clone standardmäßig buchstäblich klont gesamte Repository, einschließlich der Dinge, für die man normalerweise keine Bandbreite verschwenden möchte, wie nicht referenzierte Commits. Entnommen aus SO 4811434 .
- es macht
git fetch <remote> --tags
ineffiziente Bandbreite, aber nicht unbedingt ineffizienter Speicherplatz. Sie können Ihren Kollegen immer davon abraten, sie zu verwenden.
- müssen Sie in regelmäßigen Abständen eine
git gc
Trick, um Ihr Repository von Dateien zu säubern, die Sie nicht mehr benötigen.
- sie ist nicht so effizient wie bup o git-bigfiles . Aber es ist für das, was Sie vorhaben, besser geeignet und eher von der Stange. Bei Hunderttausenden von kleinen Dateien oder bei Dateien im Gigabyte-Bereich werden Sie wahrscheinlich auf Probleme stoßen, aber lesen Sie weiter, um Abhilfe zu schaffen.
Hinzufügen der Binärdateien
Bevor Sie beginnen, vergewissern Sie sich, dass Sie alle Änderungen übertragen haben, dass Ihr Arbeitsbaum auf dem neuesten Stand ist und dass Ihr Index keine nicht übertragenen Änderungen enthält. Es könnte eine gute Idee sein, alle Ihre lokalen Zweige auf Ihr Remote-System (Github usw.) zu übertragen, für den Fall, dass eine Katastrophe eintritt.
- Erstellen Sie einen neuen verwaisten Zweig.
git checkout --orphan binaryStuff
reicht aus. Dies erzeugt einen Zweig, der von allen anderen Zweigen völlig losgelöst ist, und die erste Übertragung, die Sie in diesem Zweig vornehmen, hat keine Eltern, was sie zu einer Root-Übertragung macht.
- Bereinigen Sie Ihren Index mit
git rm --cached * .gitignore
.
- Atmen Sie tief durch und löschen Sie den gesamten Arbeitsbaum mit
rm -fr * .gitignore
. Intern .git
bleibt unangetastet, da das Verzeichnis *
Platzhalter nicht übereinstimmt.
- Kopieren Sie Ihre VeryBigBinary.exe, oder Ihr VeryHeavyDirectory/.
- Hinzufügen && Übertragen.
- Jetzt wird es knifflig - wenn Sie es als Zweig in das Remote-System schieben, werden alle Ihre Entwickler es herunterladen, wenn sie das nächste Mal die
git fetch
die ihre Verbindung blockieren. Sie können dies vermeiden, indem Sie einen Tag statt einer Verzweigung pushen. Dies kann sich jedoch auf die Bandbreite und den Dateisystemspeicher Ihrer Kollegen auswirken, wenn diese die Angewohnheit haben, Folgendes einzugeben git fetch <remote> --tags
aber lesen Sie weiter, um eine Lösung zu finden. Machen Sie weiter und git tag 1.0.0bin
- Schieben Sie Ihr verwaistes Tag
git push <remote> 1.0.0bin
.
- Damit Sie Ihren Binärzweig nicht aus Versehen verschieben, können Sie ihn löschen
git branch -D binaryStuff
. Ihr Commit wird nicht für die Garbage Collection markiert, weil ein verwaistes Tag darauf verweist 1.0.0bin
reicht aus, um sie am Leben zu erhalten.
Auschecken der Binärdatei
- Wie kann ich (oder meine Kollegen) die VeryBigBinary.exe in den aktuellen Arbeitszweig auschecken? Wenn Ihr aktueller Arbeitszweig zum Beispiel master ist, können Sie einfach
git checkout 1.0.0bin -- VeryBigBinary.exe
.
- Dies wird fehlschlagen, wenn Sie nicht über das Orphan-Tag verfügen
1.0.0bin
heruntergeladen, in diesem Fall müssen Sie git fetch <remote> 1.0.0bin
im Vorfeld.
- Sie können die
VeryBigBinary.exe
in Ihr Masterstudium .gitignore
damit niemand in Ihrem Team die Hauptgeschichte des Projekts versehentlich mit dem Binärcode verunreinigt.
Vollständige Löschung der Binärdatei
Wenn Sie VeryBigBinary.exe vollständig aus Ihrem lokalen Repository, Ihrem entfernten Repository und den Repositorys Ihrer Kollegen entfernen möchten, können Sie dies einfach tun:
- Löschen Sie das verwaiste Tag auf der Fernbedienung
git push <remote> :refs/tags/1.0.0bin
- Das verwaiste Tag lokal löschen (löscht alle anderen nicht referenzierten Tags)
git tag -l | xargs git tag -d && git fetch --tags
. Entnommen aus SO 1841341 mit leichten Änderungen.
- Verwenden Sie einen git gc-Trick, um Ihren nicht mehr referenzierten Commit lokal zu löschen.
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
. Es werden auch alle anderen nicht referenzierten Commits gelöscht. Entnommen aus SO 1904860
- Wenn möglich, wiederholen Sie den Trick mit git gc auf der Gegenstelle. Dies ist möglich, wenn Sie Ihr Repository selbst hosten. Bei einigen Git-Anbietern wie Github oder in einigen Unternehmensumgebungen ist dies möglicherweise nicht möglich. Wenn Sie Ihr Repository bei einem Anbieter hosten, der Ihnen keinen ssh-Zugang zum Remote-Repository gewährt, lassen Sie es einfach bleiben. Es ist möglich, dass die Infrastruktur Ihres Providers Ihre nicht referenzierte Übergabe in ihrer eigenen Zeit bereinigt. Wenn Sie in einem Unternehmen arbeiten, können Sie Ihrer IT-Abteilung raten, einmal pro Woche einen Cron-Job auszuführen, der Ihre Remote-Daten abholt. Ob sie das tun oder nicht, hat keine Auswirkungen auf Ihr Team in Bezug auf Bandbreite und Speicherplatz, solange Sie Ihren Kollegen raten, immer
git clone -b master --single-branch <url>
anstelle von git clone
.
- Alle Kolleginnen und Kollegen, die veraltete verwaiste Etiketten loswerden wollen, müssen nur die Schritte 2-3 ausführen.
- Sie können dann die Schritte 1-8 von Hinzufügen der Binärdateien um ein neues verwaistes Etikett zu erstellen
2.0.0bin
. Wenn Sie sich Sorgen machen, dass Ihre Kollegen tippen git fetch <remote> --tags
Sie können es tatsächlich wieder benennen 1.0.0bin
. Dadurch wird sichergestellt, dass beim nächsten Abruf aller Tags die alten 1.0.0bin
wird nicht referenziert und für eine spätere Garbage Collection markiert (mit Schritt 3). Wenn Sie versuchen, ein Tag auf der Gegenstelle zu überschreiben, müssen Sie -f
wie diese: git push -f <remote> <tagname>
Nachwort
-
OTABS berührt weder Ihren Master- noch einen anderen Quellcode-/Entwicklungszweig. Die Commit-Hashes, die gesamte Historie und die geringe Größe dieser Zweige bleiben davon unberührt. Wenn Sie Ihre Quellcode-Historie bereits mit Binärdateien aufgebläht haben, müssen Sie diese in einem separaten Arbeitsschritt bereinigen. Dieses Skript nützlich sein könnte.
-
Bestätigt, dass es unter Windows mit git-bash funktioniert.
-
Es ist eine gute Idee, ein Satz von Standard-Triks um die Speicherung von Binärdateien effizienter zu gestalten. Häufiges Ausführen von git gc
(ohne zusätzliche Argumente) sorgt dafür, dass Git die zugrunde liegende Speicherung Ihrer Dateien durch die Verwendung binärer Deltas optimiert. Wenn es jedoch unwahrscheinlich ist, dass Ihre Dateien von Commit zu Commit gleich bleiben, können Sie binäre Deltas ganz abschalten. Da es keinen Sinn macht, bereits komprimierte oder verschlüsselte Dateien wie .zip, .jpg oder .crypt zu komprimieren, können Sie die Komprimierung des zugrunde liegenden Speichers abschalten. Leider handelt es sich dabei um eine Alles-oder-Nichts-Einstellung, die auch Ihren Quellcode betrifft.
-
Vielleicht möchten Sie Teile von OTABS mit einem Skript versehen, um eine schnellere Nutzung zu ermöglichen. Insbesondere die Scripting-Schritte 2-3 von Vollständiges Löschen von Binärdateien in eine update
git hook könnte git fetch eine zwingende, aber vielleicht gefährliche Semantik verleihen ("alles holen und löschen, was veraltet ist").
-
Sie können den Schritt 4 von Vollständiges Löschen von Binärdateien um eine vollständige Historie aller binären Änderungen auf dem entfernten Rechner zu erhalten, ohne dass das zentrale Repository aufgebläht wird. Lokale Repositories werden mit der Zeit schlank bleiben.
-
In der Java-Welt ist es möglich, diese Lösung zu kombinieren mit maven --offline
um ein reproduzierbares Offline-Build zu erstellen, das vollständig in Ihrer Versionskontrolle gespeichert ist (mit Maven ist das einfacher als mit Gradle). In der Golang-Welt ist es möglich, auf diese Lösung zu bauen, um Ihren GOPATH zu verwalten, anstatt go get
. In der Python-Welt ist es möglich, dies mit virtualenv zu kombinieren, um eine in sich geschlossene Entwicklungsumgebung zu schaffen, ohne für jeden Build von Grund auf auf PyPi-Server angewiesen zu sein.
-
Wenn sich Ihre Binärdateien sehr häufig ändern, wie z.B. Build-Artefakte, könnte es eine gute Idee sein, eine Lösung zu skripten, die die 5 aktuellsten Versionen der Artefakte in den Orphan-Tags speichert monday_bin
, tuesday_bin
, ..., friday_bin
und auch ein Orphan-Tag für jede Veröffentlichung 1.7.8bin
2.0.0bin
, usw. Sie können die weekday_bin
und löschen Sie alte Binärdateien täglich. Auf diese Weise erhalten Sie das Beste aus zwei Welten: Sie behalten die gesamte Geschichte Ihres Quellcodes, sondern nur die . Historie Ihrer Binärabhängigkeiten. Es ist auch sehr einfach, die Binärdateien für ein bestimmtes Tag zu erhalten ohne den gesamten Quellcode mit seiner gesamten Historie zu erhalten: git init && git remote add <name> <url> && git fetch <name> <tag>
sollte dies für Sie tun.