Warum benötigen Git / Mercurial-Repositorys weniger Speicherplatz?

15

Ich habe in mehreren Diskussionen hier und in SO gelesen, dass DVCS-Repositorys ungefähr denselben oder weniger Speicherplatz beanspruchen als ihre zentralisierten Gegenstücke. Ich habe es vielleicht verpasst, aber ich habe keine gute Erklärung dafür gefunden, warum das so ist. Weiß jemand?

Alex Florescu
quelle
5
Sind die folgenden Infg-Posts die, die Sie gelesen haben? stackoverflow.com/questions/7727791/… oder stackoverflow.com/questions/8657710/… oder stackoverflow.com/questions/456336/…
VonC
1
Ich habe nicht, danke! Ich verstehe aus diesen Gründen, dass es zwei Antworten gibt: Komprimierung mit zlib und Speichern von Objekten als Paketdateien, wenn dies möglich ist. Die Beispiele von Mozilla sind auch großartig!
Alex Florescu
1
@Alex Nein, das vermisst den Hauptgrund. SVN speichert vollständige Snapshots, Git und Mercurial speichern nur die HEAD-Revision und die Unterschiede. Bei Verwendung der herkömmlichen Komprimierung können Sie im besten Fall eine Komprimierungsrate von etwa 60–80% erzielen. Die Verwendung von Diffs kann bis zu 99% ergeben. Diese Zahlen werden mir allerdings aus dem Arsch gezogen - echte Zahlen können abweichen; Die Tendenz wird jedoch dieselbe sein.
Konrad Rudolph
@KonradRudolph, ist das nicht alles, worum es bei Packfiles geht?
Alex Florescu
@ Alex Nicht wirklich. Soweit ich das Packfile wissen zusätzlich wird die Verpackung mehrere Dateien in einem. Dies hängt nicht unbedingt zusammen.
Konrad Rudolph

Antworten:

18

Aus eigener Erfahrung sind folgende Aussagen zutreffend:

  • Git ist sehr effizient beim Speichern von Textdateien und speichert nur diese Dateien, die geändert wurden. Wenn Sie also SVN und Git vergleichen, um die Repository-Größen zu vergleichen, können sie ähnlich sein oder es kann sogar einen kleinen Vorteil für Git geben.
  • Dies ist völlig falsch, wenn Sie die Größe von Repositorys vergleichen, bei denen es sich bei einer erheblichen Anzahl von Dateien um Office-Dateien handelt (z. B. MS Word, Excel, PowerPoint usw.). Hier speichert Git auch vollständige Kopien, was bedeutet, dass 10 kleine Änderungen auf einem PowerPoint-Folienstapel zu 10 vollständigen Kopien führen, wobei Subversion nur ein binäres Diff speichert, das um den Faktor 100 kleiner sein kann.

Wenn Sie den Checkout-Speicherort (bei dem es sich um ein Repository für sich selbst handelt) mit Git vergleichen, sieht die Geschichte ganz anders aus:

  • Subversion speichert für jede Datei eine vollständige Kopie, sodass die Größe Ihres Checkout-Speicherorts normalerweise das Zweifache der Größe der Dateien selbst beträgt.
  • Git speichert den vollständigen Verlauf des Repositorys lokal. Abhängig von der Größe des Verlaufs kann dieser kleiner oder viel größer sein als der der Subversion-Checkout-Kopie.

Wenn Sie die Anzahl der Bytes vergleichen, die Sie herunterladen oder hochladen müssen, ist dies wieder anders.

  • Subversion muss normalerweise weniger Bytes senden oder empfangen, da es nur Unterschiede sendet. Dies muss bei jedem Commit und Update erfolgen.
  • Git muss (anfangs) das gesamte Repository abrufen und sendet dann vollständige Dateien (komprimiert?), Die für Textdateien nicht so unterschiedlich sind, für Binärdateien jedoch unterschiedlich sein können. Und ja, Git tut dies nur, wenn Sie etwas in das Remote-Repository verschieben oder daraus ziehen.

Am Ende vergleichen Sie also Äpfel mit Orangen, und je nachdem, was Sie mit Subversion oder Git machen möchten, kann das Ergebnis unterschiedlich sein.


@jk fragte nach vollständigen Kopien oder binären Diffs, und ich konnte diese Frage nicht beantworten. Ich habe Matthew McCullough gefragt, der kürzlich auf der Jax 2012 einen Git-Workshop gegeben hat (den ich besucht habe). Er hat sich die Zeit genommen (vielen Dank an ihn), um mit einer detaillierten Zusammenfassung die innere Arbeitsweise von Git zu erklären . Also ja, dort wird eine Komprimierung durchgeführt (und ich werde auch ein Experiment mit einer Microsoft Office-Datei durchführen und das mit seinem Inhalt vergleichen), aber nein, die Komprimierung wird für die gesamte Datei durchgeführt. Aus seinem Kern zitieren:

Lose Objekte werden zum Zeitpunkt jedes Commits in einem komprimierten, aber nicht im Delta-Format vorliegenden Format geschrieben.

mliebelt
quelle
1
Sind Sie sicher, dass Git vollständige Kopien von Office-Dateien speichert? Ich denke, es speichert auch binäre Unterschiede. Das eigentliche Problem bei dieser Art von Dateien ist natürlich, dass sie oftmals bereits komprimiert sind, sodass eine kleine Änderung dazu führen kann, dass sich die gesamte Datei ändert
jk.
2
Fragte jemand (per E-Mail), der viel mehr weiß als ich, und wird seine Antwort dann in meine Antwort aufnehmen.
mliebelt
6
Git behandelt Text- und Binärdateien in Bezug auf die Speicherung in jeder Hinsicht genauso. Die losen vs. gepackten Objekte haben nichts mit Text vs. Binär zu tun. Der Grund, warum Binärdateien häufig zu viel größeren Unterschieden führen als Textdateien, ist, dass viele Binärformate (einschließlich aller neuen Office-Formate) bereits komprimiert sind und daher selbst eine kleine Änderung des Inhalts häufig eine große Änderung des resultierenden Binärblobs verursacht. Dies ist für Git und Subversion gleichermaßen von Belang, aber Subversion verbraucht nur die Strafe auf dem Server, während Git überall ist.
Jan Hudec
4
Die losen vs. gepackten Objekte haben nichts mit Text vs. Binär zu tun. Es ist eine Amortisation der schwierigen Arbeit, die binären Diffs zu finden. Die Geschwindigkeit ist ein wichtiges Merkmal von git. Während des regulären Betriebs komprimiert git nur die neuen Daten und legt sie im Repository ab. Das sind lose Gegenstände. Wenn Sie danach fragen, indem Sie anrufen, git gcoder wenn sich zu viele lose Objekte ansammeln, werden gute Kandidaten für eine Delta-Komprimierung gefunden (Git kann sich von der vorherigen Version unterscheiden), die Deltas werden in einer "Packung" gespeichert und die losen Objekte werden entfernt.
Jan Hudec
3
Für diejenigen, die sich für reale Zahlen interessieren: Ich habe gerade zwei Arbeitskopien des exakt gleichen Repos verglichen. Die SVN-Arbeitskopie hat ca. 2,9 GB, die GIT- Arbeitskopie ca. 0,8 GB.
JensG