Git ist sehr, sehr langsam, wenn große Binärdateien verfolgt werden

83

Mein Projekt ist sechs Monate alt und Git ist sehr, sehr langsam. Wir verfolgen rund 30 Dateien mit einer Größe von 5 MB bis 50 MB. Das sind Binärdateien und wir halten sie in Git. Ich glaube, diese Dateien machen Git langsam.

Gibt es eine Möglichkeit, alle Dateien mit einer Größe von> 5 MB aus dem Repository zu löschen? Ich weiß, dass ich all diese Dateien verlieren würde und das ist okay für mich.

Idealerweise hätte ich gerne einen Befehl, der alle großen Dateien (> 5 MB) auflistet. Ich kann die Liste sehen und dann sage ich okay, mach weiter und lösche diese Dateien und mache Git schneller.

Ich sollte erwähnen, dass git nicht nur auf meinem Computer langsam ist, sondern die Bereitstellung der App in einer Staging-Umgebung jetzt etwa 3 Stunden dauert.

Das Update sollte sich also auf den Server und nicht nur auf die Benutzer des Repositorys auswirken.

Nick Vanderbilt
quelle
4
Sie können versuchen, Git aus dem git-bigfilesProjekt zu verwenden
Jakub Narębski
1
Vielleicht möchten Sie versuchen, etwas wie git-annex für die Verwaltung von Binärdateien zu verwenden. git-annex.branchable.com
Jed Schneider
Für den Fall, dass es für jemanden nützlich ist, möchte ich hinzufügen, dass meine Cygwin-Version von git an Rebases hängt. Als ich Git-Bash verwendete, hatte dasselbe Repository keine Probleme.
Sridhar Sarnobat
Ich frage mich, ob dies immer noch der Fall ist. Ich hoffe, sie deaktivieren die Komprimierung für alles, wo der Komprimierungseffekt unter 50% liegt (oder für jedes andere wählbare X%). Irgendwann überwiegt die Geschwindigkeit deutlich den Hardware-Platz!
Trilarion

Antworten:

125

Sammeln Sie Müll?

git gc

Dies macht einen signifikanten Geschwindigkeitsunterschied, selbst bei kleinen Repos.

kubi
quelle
8
Dies erfolgt automatisch, wenn zu viel Unordnung auftritt. Ich bezweifle, dass es dem OP wirklich helfen wird.
Cascabel
@ Jefromi, ist das neu? Ich habe gestern gerade ein Upgrade auf 1.7.1 durchgeführt, aber zuvor wurde die von mir verwendete Version definitiv nicht automatisch ausgeführt gc.
Kubi
@kubi: Nun, es gibt es nicht für immer, aber es ist nicht gerade neu - es wurde seit caf9de2 (14. September 2007) oder in der stabilen Version v1.5.4 (1. Februar 2008) aus Commit, Merge, Am und Rebase aufgerufen ).
Cascabel
1
Beim zweiten Gedanken git gckann unmöglich aufgerufen werden commitund würde mergesonst git fsck --unreachablenie etwas zurückgeben.
Kubi
4
Fand es. Die Standardanzahl loser Objekte vor der automatischen gcAusführung beträgt 6700. Dies erklärt, warum ich sie noch nie ausgeführt habe.
Kubi
79

Erläuterung

Git ist wirklich gut in großen Historien kleiner Textdateien, weil es sie und ihre Änderungen effizient speichern kann. Gleichzeitig ist git bei Binärdateien sehr schlecht und speichert naiv separate Kopien der Datei ( zumindest standardmäßig ). Das Repository wird riesig und dann langsam, wie Sie beobachtet haben.

Dies ist ein häufiges Problem bei DVCS, das durch die Tatsache verschärft wird, dass Sie bei jedem Klonen jede Version jeder Datei ("das gesamte Repository") herunterladen. Die Jungs von Kiln arbeiten an einem Plugin, um diese großen Dateien eher wie Subversion zu behandeln, das nur historische Versionen auf Anfrage herunterlädt.

Lösung

Dieser Befehl listet alle Dateien im aktuellen Verzeichnis mit der Größe> = 5 MB auf.

find . -size +5000000c 2>/dev/null -exec ls -l {} \;

Wenn Sie die Dateien aus dem gesamten Verlauf des Repositorys entfernen möchten, können Sie diese Idee verwenden git filter-branch, um den Verlauf zu durchlaufen und alle Spuren großer Dateien zu entfernen . Danach werden alle neuen Klone des Repositorys schlanker. Wenn Sie ein Repository ohne Klonen einrichten möchten, finden Sie Anweisungen auf der Manpage (siehe "Checkliste zum Verkleinern eines Repositorys").

git filter-branch --index-filter \
    'find . -size +5000000c 2>/dev/null -exec git rm --cached --ignore-unmatch {} \;'

Ein Wort der Warnung : Dadurch wird Ihr Repository nicht mit anderen Klonen kompatibel , da in den Bäumen und Indizes unterschiedliche Dateien eingecheckt sind. Sie können nicht mehr von ihnen drücken oder ziehen.

Andres Jaan Tack
quelle
4
Hinweis: Dies ist die Unix / Linux-Version von find, nicht die Windows-Datei find.exe.
Craig Trader
1
+1. Möglicherweise möchten Sie die Ausgabe zuerst findan eine Datei senden , die Liste überprüfen und dann verwenden git rm, nur für den Fall, dass falsche Treffer vorliegen. Alternativ können Sie git statusnach dem Entfernen großer Dateien überprüfen, ob git checkout HEAD <file>versehentlich entfernte Dateien wiederhergestellt wurden.
Cascabel
2
Ich denke, Ihr Kommentar, dass git "standardmäßig separate Kopien speichert", ist rückwärts. Gemäß der E-Mail-Kette, mit der Sie verknüpft sind ( thread.gmane.org/gmane.comp.version-control.git/146957/… ), versucht git standardmäßig, die Binärdateien zu unterscheiden - und genau das verursacht das Problem. nicht die Lagerung.
Alexander Bird
16

Hier ist eine zensierte Revision, die weniger negativ und entzündlich sein soll:

Git hat eine bekannte Schwäche, wenn es um Dateien geht, die keine zeilenweisen Textdateien sind. Derzeit gibt es keine Lösung und keine Pläne des Git-Kernteams, dies zu beheben. Es gibt Problemumgehungen, wenn Ihr Projekt klein ist, z. B. 100 MB oder so. Es gibt Zweige des Git-Projekts, um dieses Skalierbarkeitsproblem zu beheben, aber diese Zweige sind derzeit noch nicht ausgereift. Einige andere Revisionskontrollsysteme haben dieses spezielle Problem nicht. Sie sollten dieses Problem als einen von vielen Faktoren betrachten, wenn Sie entscheiden, ob Sie git als Ihr Revisionskontrollsystem auswählen möchten.

John
quelle
8
"Git hat eine bekannte Schwäche ..." - Zitat erforderlich
Nav
6
Ich weiß es. Wer braucht Zitate, wenn es tatsächlich allgemein bekannt ist. benutze git einfach nicht für binär. Verwenden Sie Perforce oder spezialisiertes Asset Management.
v.oddou
1
@ v.oddou Nun, es gibt einen Unterschied zwischen "Ich weiß es" und "seinem tatsächlichen Allgemeinwissen". Diese Sache ist, dass nicht jeder es weiß und es wahrscheinlich nicht einmal ganz wahr ist. Jede Art von Zitat verbessert diese Antwort. Es ist okay, aber sicherlich nicht herausragend und gesichert.
Trilarion
2
Nun, um dem Feuer keinen Treibstoff hinzuzufügen, aber wenn Sie eine Google-Suche nach "Git und Binärdateien langsam" durchführen, werden viele Links gefunden, die Benutzer melden, die Probleme beim Verwalten von Binärdateien in Git haben. Entwickler, die das eine oder andere SCM verwenden, kennen die Stärken und Schwächen jedes Systems. Daher hat sich git den Ruf erarbeitet, sehr langsam zu werden, wenn Binärdateien in ein Repo geworfen werden.
AhiyaHiya
15

Binärdateien und die Art und Weise, wie Git mit ihnen umgeht, sind nicht spezifisch. Wenn Sie eine Datei zu einem Git-Repository hinzufügen, wird ein Header hinzugefügt und die Datei mit zlib komprimiert und nach dem SHA1-Hash umbenannt. Dies ist unabhängig vom Dateityp genau gleich. Es gibt nichts in der zlib-Komprimierung, was es für Binärdateien problematisch macht.

Aber an einigen Stellen (Pushing, GC) beginnt Git, die Möglichkeit zu prüfen, Inhalte zu deltakomprimieren. Wenn git ähnliche Dateien findet (Dateiname usw.), werden sie in den Arbeitsspeicher gestellt und zusammen komprimiert. Wenn Sie 100 Dateien haben und jede von ihnen 50 MB sagt, wird versucht, 5 GB gleichzeitig in den Speicher zu legen. Dazu müssen Sie noch etwas hinzufügen, damit die Dinge funktionieren. Ihr Computer verfügt möglicherweise nicht über diese RAM-Größe und beginnt zu tauschen. Der Prozess braucht Zeit.

Sie können die Tiefe der Delta-Komprimierung begrenzen, damit der Prozess nicht so viel Speicher belegt, das Ergebnis jedoch eine weniger effiziente Komprimierung ist. (core.bigFileThreshold, Delta-Attribut, pack.window, pack.depth, pack.windowMemory usw.)

Es gibt also viele Möglichkeiten, wie Sie Git dazu bringen können, mit großen Dateien sehr gut zu funktionieren.

Martin
quelle
4
Sehen Sie hier für eine Erklärung, wie geschieht diese „Delta“ Versuche von abzuschalten.
Alexander Bird
6

Eine Möglichkeit, die Dinge zu beschleunigen, besteht darin, die --depth 1Flagge zu verwenden. Weitere Informationen finden Sie in der Manpage. Ich bin kein großer Git-Guru, aber ich glaube, dies sagt, mach das Äquivalent von a p4 getoder an svn get, das heißt, es gibt dir nur die neuesten Dateien, anstatt "gib mir alle Revisionen aller Dateien durchgehend" was git clonemacht.

David
quelle
1
Auf diese Weise können Sie keine Push-Vorgänge aus dem Repository ausführen. Daher ist dies nur von begrenztem Nutzen.
Martin C. Martin
4

Hast du Git gesagt, dass diese Dateien binär sind?

zB *.ext binaryzu Ihrem Repository hinzugefügt.gitattributes

sml
quelle
Ich gehe davon aus, dass das Erzählen von Git, dass Dateien binär sind, die Sache beschleunigt.
Nick Vanderbilt
Es kann sein, dass die Heuristik von Git nicht erkennen kann, dass eine Datei automatisch binär ist.
sml
2

Ich habe Git seit 2008 sowohl unter Windows als auch unter GNU / Linux ausgeführt und die meisten Dateien, die ich verfolge, sind Binärdateien. Einige meiner Repos haben mehrere GB und enthalten JPEG und andere Medien. Ich habe viele Computer sowohl zu Hause als auch bei der Arbeit, auf denen Git ausgeführt wird.

Ich hatte noch nie die Symptome, die im ursprünglichen Beitrag beschrieben sind. Aber vor ein paar Wochen habe ich MsysGit auf einem alten Win-XP-Laptop installiert und fast alles, was ich getan habe, hat git zum Stillstand gebracht. Selbst der Test mit nur zwei oder drei kleinen Textdateien war lächerlich langsam. Wir sprechen über 10 Minuten, um eine Datei mit weniger als 1 KB hinzuzufügen ... es scheint, als ob die Git-Prozesse für immer am Leben geblieben sind. Alles andere funktionierte wie erwartet auf diesem Computer.
Ich habe ein Downgrade von der neuesten Version auf 1.6 durchgeführt und die Probleme waren behoben ...
Ich habe andere Laptops derselben Marke, auch mit Win-XP, das von derselben IT-Abteilung installiert wurde, mit demselben Image, wobei Git unabhängig von der Version einwandfrei funktioniert. .. Also muss es etwas Seltsames mit diesem bestimmten Computer geben.

Ich habe auch einige Tests mit Binärdateien und Komprimierung durchgeführt. Wenn Sie ein BMP-Bild haben und kleine Änderungen daran vornehmen und diese festschreiben, wird git gc sehr gut komprimiert. Mein Fazit ist also, dass die Komprimierung nicht davon abhängt, ob die Dateien binär sind oder nicht.

Martin
quelle
-2

Richten Sie die Dateien einfach so ein, dass sie ignoriert werden. Siehe den Link unten:

http://help.github.com/git-ignore/

Joshlroger
quelle
@Jefromi Wenn Sie sich den Link ansehen, den ich gepostet habe, werden Sie sehen, dass der zweite Absatz Anweisungen enthält, die ihm genau sagen, was er in diesem Fall tun soll.
Joshlrogers
14
Wahr. Der direkte Inhalt Ihrer Antwort lautet jedoch "Dateien ignorieren", nicht "Dateien aus der Verfolgung entfernen und dann ignorieren". Es ist im Allgemeinen besser, es hier zu schreiben, als auf eine andere Site zu verlinken.
Cascabel
-24

Das liegt daran, dass Git nicht skalierbar ist.

Dies ist eine schwerwiegende Einschränkung bei Git, die durch die Befürwortung von Git übertönt wird. Durchsuchen Sie die Git-Mailinglisten und Sie werden Hunderte von Benutzern finden, die sich fragen, warum nur magere 100 MB Bilder (z. B. für eine Website oder Anwendung) Git in die Knie zwingen. Das Problem scheint zu sein, dass fast alle Git auf einer Optimierung beruhen, die sie als "Packen" bezeichnen. Leider ist das Packen für alle außer den kleinsten Textdateien (dh Quellcode) ineffizient. Schlimmer noch, es wird mit zunehmender Geschichte immer weniger effizient.

Es ist wirklich ein peinlicher Fehler in Git, der (trotz fehlender Beweise) als "schnell" angepriesen wird, und die Git-Entwickler sind sich dessen sehr wohl bewusst. Warum haben sie es nicht behoben? Auf der Git-Mailingliste finden Sie Antworten von Git-Entwicklern, die das Problem nicht erkennen, da sie Photoshop-Dokumente (* .psd) im proprietären Format haben. Ja, es ist wirklich so schlimm.

Hier ist das Ergebnis:

Verwenden Sie git für winzige Projekte, die nur aus Quellcode bestehen und für die Sie kein separates Repo einrichten möchten. Oder nur für kleine Quellcode-Projekte, bei denen Sie das git-Modell des gesamten Repo-Modells der dezentralen Entwicklung nutzen möchten. Oder wenn Sie einfach ein neues Werkzeug lernen möchten. All dies sind gute Gründe, Git zu verwenden, und es macht immer Spaß, neue Tools zu lernen.

Verwenden Sie git nicht, wenn Sie eine große Codebasis, Binärdateien, einen großen Verlauf usw. haben. Nur eines unserer Repos ist eine TB. Git kann damit nicht umgehen. VSS, CVS und SVN können damit problemlos umgehen. (SVN bläht sich jedoch auf.)

Geben Sie git auch Zeit zum Reifen. Es ist noch unreif, aber es hat viel Schwung. Mit der Zeit denke ich, dass die praktische Natur von Linus die OSS-Puristen überwinden wird und Git irgendwann im größeren Bereich eingesetzt werden kann.

John
quelle
15
Diese Antwort ist wirklich übermäßig negativ und entzündlich. Ja, Git hat Skalierbarkeitsprobleme mit Binärdateien . Es ist ziemlich skalierbar und schnell für Code. Es gibt viele Hinweise auf die Geschwindigkeit (trotz Ihrer gegenteiligen Behauptung), auch wenn die Tatsache nicht berücksichtigt wird, dass CVS / SVN für viele Vorgänge Netzwerkzugriff anstelle von Festplattenzugriff erfordern. Es gibt viele große Projekte mit einer großen Geschichte, die Git sehr gerne verwenden.
Cascabel
8
Und ... du machst das Photoshop-Ding? Ich werde meine Zeit nicht damit verschwenden, eine detaillierte Antwort zu schreiben, aber wenn ich den gesamten Thread gelesen habe thread.gmane.org/gmane.comp.version-control.git/146957/… (vielleicht ärgern Sie sich, weil der John in der Thread bist du?), ich sehe viele vernünftige Antworten darüber, wie man mit aktuellem Git am besten damit umgeht, wie es in Zukunft angegangen werden könnte und warum es nicht ihre erste Priorität ist.
Cascabel
14
Ja, ich glaube nicht, dass du hier Recht hast. Git funktioniert viel zu gut, als dass der Linux-Kernel eine Ablehnung verdient hätte: "Ist nicht skalierbar."
Andres Jaan Tack
1
Dieser Kommentar wäre glaubwürdiger, wenn er Links oder Daten zum Sichern hätte. Übrigens, was denkst du über Quecksilber?
vy32
3
Vielleicht äußert er keine populäre Meinung, aber ich denke, dass das Down-Voting in seiner "Negativität" übertrieben war als die Antwort des OP. Wir sollten zu Meinungsverschiedenheiten ermutigen, nicht nur, weil jemand den Versionskontrollgeschmack des Jahres nicht mag. GIT ist wirklich nicht gut zum Verfolgen von Binärdateien geeignet. Aber es funktioniert hervorragend für Quellcode, es ist in erster Linie beabsichtigt, weshalb es im Linux-Kernel wunderbar funktioniert.
Dyasta