31

Ich habe ein Git-Repo mit einigen sehr großen Binärdateien drin. Ich brauche sie nicht mehr und es ist mir egal, ob ich die Dateien aus früheren Commits auschecken kann. Um also die Repo-Größe zu reduzieren, möchte ich die Binaries komplett aus der History löschen.Aktualisieren Sie ein Entwickler-Team mit neu geschriebenen Git Repo Geschichte, Entfernen von großen Dateien

Nach einer Web-Suche, stellte ich fest, dass meine beste (nur?) Option zu verwenden ist git-filter-branch:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' HEAD 

dies so weit wie ein guter Ansatz scheint?

Angenommen, die Antwort ist ja, ich habe ein anderes Problem zu kämpfen. Die git manual has this warning:

WARNUNG! Der neu geschriebene Verlauf wird für alle Objekte unterschiedliche Objektnamen haben und nicht mit dem ursprünglichen Zweig konvergieren. Sie werden nicht in der Lage sein, den umgeschriebenen Zweig auf den ursprünglichen Zweig zu schieben und zu verteilen. Bitte verwenden Sie diesen Befehl nicht, wenn Sie die vollständigen Implikationen nicht kennen, und vermeiden Sie es trotzdem, wenn ein einfaches einzelnes Commit ausreichen würde, um Ihr Problem zu beheben. (Siehe "Fehlgeschlagene UPSTREAM REBASE" in git-rebase (1) für weitere Informationen über veröffentlichte Geschichte neu zu schreiben.)

Wir sind auf unserem Server eine Remote-Repo haben. Jeder Entwickler schiebt an und zieht daraus. Basierend auf der obigen Warnung (und meinem Verständnis davon, wie git-filter-branch funktioniert), glaube ich nicht, dass ich in der Lage sein werde, git-filter-branch auf meiner lokalen Kopie auszuführen und dann die Änderungen zu übertragen.

Also, ich habe vor, versuchsweise durch die folgenden Schritte zu gehen:

  1. alle meine Entwickler per eMail zu begehen, Push-und Stopp für ein bisschen arbeiten.
  2. Melden Sie sich beim Server an und führen Sie den Filter auf dem zentralen Repo aus.
  3. Lassen Sie alle ihre alten Kopien löschen und erneut vom Server klonen.

Klingt das richtig? Ist das die beste Lösung?

+2

Es kommt mir jetzt, dass die * einfachste *, was zu tun sein könnte Ihre Entwickler jedem Lauf die haben identischer 'git-filter-branch' Befehl. Sie sollten mit Geschichten enden, die identisch mit denen sind, die Sie erstellt haben, ohne dass Sie sie erneut klonen oder manuell umbauen müssen. –

+1

@BenJackson die Code-Dateien wären identisch, aber die Commit-Objekte werden verschiedene Committer-Metadaten durch die Rebase hinzugefügt haben. – Douglas

+1

@Douglas Ich glaube nicht, dass 'git filter-branch' Committer-Daten ändert, wenn Sie nicht explizit danach gefragt werden. ('git commit --rebase' tut, aber nicht' git filter-branch', soweit ich das sehen kann.) – cdhowie

Antwort

18

Ja, Ihre Lösung wird funktionieren. Sie haben auch eine andere Option: Anstatt dies im zentralen Repo zu tun, führen Sie den Filter auf Ihrem Klon aus und drücken Sie ihn dann mit git push --force --all zurück. Dadurch wird der Server gezwungen, die neuen Zweige aus Ihrem Repository zu akzeptieren. Dies ersetzt nur Schritt 2; Die anderen Schritte werden gleich sein.

Wenn Ihre Entwickler ziemlich gitfähig sind, müssen sie ihre alten Kopien möglicherweise nicht löschen. zum Beispiel könnten sie die neuen Fernbedienungen holen und ihre Zweigstellen entsprechend neu aufstellen.

+0

Dies berücksichtigt nicht alle Fälle. Wenn es Tags oder andere Zweige gibt, sollten Sie alle '--tag-name-filter cat' und' --all' anstelle von HEAD zu den git filter-branch-Optionen setzen. Siehe meine Antwort für weitere Informationen. –

5

Wenn Sie Ihre Entwickler nicht erneut klonen lassen, ist es wahrscheinlich, dass sie es schaffen, die großen Dateien zurück zu ziehen. Zum Beispiel, wenn sie sorgfältig auf den neuen Verlauf splitten und dann mit git merge von lokalen Projektzweig, der nicht rebasiert wurde, enthalten die Eltern des Zusammenführungs-Commits den Projektzweig, der schließlich auf den gesamten Verlauf zeigt, den Sie mit git filter-branch gelöscht haben.

+0

Also, mit anderen Worten, mein Plan, alle wieder zu klonen, wird eine Menge potentieller Fehler vermeiden. – rlkw1024

+1

Für Sie und das Repository.Es wird nervig für jeden sein, der eine bereits existierende Sammlung von Projekt-Filialen und -Staschen hat. –

9

Ihr Plan ist gut (obwohl es besser wäre, die Filterung auf einem nackten Klon Ihres Repository statt auf dem zentralen Server durchzuführen), aber vor git-filter-branch sollten Sie meine BFG Repo-Cleaner verwenden, eine schnellere, einfachere Alternative bis git-filter-branch speziell zum Entfernen von große Dateien von Git Repos konzipiert.

Herunterladen the Java jar (erfordert Java 6 oder höher) und diesen Befehl ausführen:

$ java -jar bfg.jar --strip-blobs-bigger-than 1MB my-repo.git 

Flecken über 1 MB groß (das ist nicht in Ihrem neuesten begehen) wird aus vollständig entfernt die Geschichte Ihres Repositories. Sie können dann git gc verwenden, um die toten Daten zu reinigen weg:

$ git gc --prune=now --aggressive 

Die BFG ist in der Regel 10-50x schneller als git-filter-branch läuft und die Optionen um diese beiden gemeinsamen Anwendungsfälle zugeschnitten sind:

  • Entfernen verrückt Big Dateien
  • Entfernen Passwörter, Credentials & andere private Daten
3

Ihre Lösung ist nicht vollständig. Sie sollten --tag-name-filter cat als Argument zum Filtern der Verzweigung angeben, damit die Tags, die die großen Dateien enthalten, ebenfalls geändert werden. Sie sollten auch alle Refs anstatt nur HEAD ändern, da das Commit in mehreren Zweigen sein könnte. Hier

ist etwas besser Code:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' --tag-name-filter cat -- --all 

Github hat eine gute Führung: https://help.github.com/articles/remove-sensitive-data

Verwandte Themen