Dlaczego repozytoria Git / Mercurial zajmują mniej miejsca?
15
Czytałem o kilku dyskusjach tutaj i na SO, że repozytoria DVCS zajmują mniej więcej tyle samo miejsca niż ich scentralizowane odpowiedniki. Mogłem to przegapić, ale nie znalazłem dobrego wyjaśnienia, dlaczego tak jest. Ktoś wie?
Nie, dziękuję! Rozumiem na podstawie tych odpowiedzi, że istnieją dwie odpowiedzi: kompresja za pomocą zlib i zapisywanie obiektów jako plików paczek, jeśli to możliwe. Przykłady z Mozilli są również świetne!
Alex Florescu
1
@Alex Nie, to pomija główny powód. SVN zapisuje pełne migawki, Git i Mercurial zapisują tylko wersję HEAD i różnice. Użycie konwencjonalnej kompresji może zapewnić najlepszy współczynnik kompresji wynoszący około 60–80% kompresji. Używanie różnic może dać ci aż 99%. Te liczby są jednak wyciągane z mojego tyłka - rzeczywiste liczby mogą się różnić; tendencja będzie taka sama, choć.
Konrad Rudolph
@KonradRudolph, czy nie o to chodzi w plikach pakietów?
Alex Florescu
@Alex Nie bardzo. O ile wiem, że packfile dodatkowo pakowania wielu plików w jeden. To niekoniecznie jest powiązane.
Konrad Rudolph
Odpowiedzi:
18
Z własnego doświadczenia wynika, że wszystkie poniższe stwierdzenia są prawdziwe:
Git jest bardzo wydajny w przechowywaniu plików tekstowych i tylko tych plików, które zostały zmienione. więc podczas porównywania SVN i Git w celu porównania rozmiarów repozytorium mogą być one podobne, a Git może mieć nawet niewielką przewagę.
Jest to całkowicie błędne, jeśli porównasz rozmiar repozytoriów, w których znaczna liczba plików to pliki biurowe (takie jak MS Word, Excel, Powerpoint, ...). Tutaj Git przechowuje również kompletne kopie, co oznacza, że 10 małych zmian na stosie slajdów PowerPointa daje 10 kompletnych kopii, przy czym Subversion przechowuje tylko różnicę binarną, która może być 100 razy mniejsza.
Jeśli porównasz lokalizację kasy (która sama w sobie jest repozytorium z Git), historia będzie zupełnie inna:
Subversion przechowuje dla każdego pliku kompletną kopię, więc rozmiar twojego miejsca kasy jest zwykle 2 razy większy niż rozmiar samych plików.
Git przechowuje lokalnie pełną historię repozytorium, więc w zależności od wielkości historii, może ona być mniejsza lub znacznie większa niż kopia kasy w Subversion.
Jeśli porównasz liczbę bajtów, które musisz pobrać lub przesłać, znowu będzie inaczej.
Subversion zwykle wysyła lub odbiera mniej bajtów, ponieważ wysyła tylko różnice. Musi to robić przy każdym zatwierdzeniu i aktualizacji.
Git musi pobrać całe repozytorium (początkowo), a następnie wysyła pełne pliki (skompresowane?), Które nie różnią się tak bardzo dla plików tekstowych, ale mogą być inne dla plików binarnych. I tak, Git robi to tylko wtedy, gdy wypychasz lub ciągniesz coś do zdalnego repozytorium.
Na koniec porównujesz jabłka z pomarańczami i w zależności od tego, co chcesz zrobić z Subversion lub Git, wynik może być inny.
@jk zapytał o kompletne kopie lub różnice binarne i nie mogłem odpowiedzieć na to pytanie. Zapytałem Matthew McCullougha, który ostatnio przeprowadził warsztaty Git na Jax 2012 (który odwiedziłem). Poświęcił czas (dziękuję mu bardzo), aby wyjaśnić ze szczegółową istotą wewnętrzne działanie Git. Więc tak, działa tam kompresja (i ja też przeprowadzę eksperyment z plikiem biurowym Microsoft i porównam go z jego treścią), ale nie, kompresja jest wykonywana dla całego pliku. Powołując się na swoją treść:
Luźne obiekty są zapisywane w skompresowanym formacie innym niż delta w momencie każdego zatwierdzenia.
czy jesteś pewien, że git przechowuje pełne kopie plików biurowych? Myślę, że przechowuje także binarne różnice. oczywiście tak naprawdę problem z tego rodzaju plikami polega na tym, że często są one już skompresowane, więc niewielka zmiana może spowodować zmianę całego pliku
jk.
2
Zapytałem kogoś (przez e-mail), który wie o wiele więcej niż ja, i wtedy uwzględni moją odpowiedź w mojej odpowiedzi.
mliebelt
6
Git traktuje pliki tekstowe i binarne dokładnie tak samo we wszystkich aspektach dotyczących przechowywania. Obiekty sypkie i spakowane nie są powiązane z tekstem a binarnie. Powodem, dla którego pliki binarne często powodują znacznie większe różnice niż pliki tekstowe, jest to, że wiele formatów binarnych (w tym wszystkie nowe formaty biurowe) są już skompresowane, a zatem nawet niewielka zmiana zawartości często powoduje dużą zmianę w wynikowym binarnym obiekcie blob. Dotyczy to równie git i subversion, ale subversion bierze karę tylko na serwer, podczas gdy git jest wszędzie.
Jan Hudec
4
Obiekty luźne vs. spakowane nie mają nic wspólnego z tekstem a binarnością. Jest to amortyzacja trudnej pracy polegającej na znalezieniu różnic binarnych. Szybkość jest ważną cechą git, dlatego podczas zwykłego działania git zamyka tylko nowe dane i umieszcza je w repozytorium. To są luźne przedmioty. Niż gdy poprosisz o to przez wywołanie git gclub nagromadzenie zbyt wielu luźnych obiektów, znajdzie dobrych kandydatów do skompresowania ich w delcie (git może różnić się w stosunku do innej niż poprzednia wersja), przechowuje delty w „paczce” i usuwa luźne obiekty.
Jan Hudec
3
Dla tych, którzy są zainteresowani liczbami z prawdziwego świata: Właśnie porównałem dwie kopie robocze z dokładnie tego samego repozytorium. Kopia robocza SVN ma około 2,9 GB, kopia robocza GIT około 0,8 GB.
Odpowiedzi:
Z własnego doświadczenia wynika, że wszystkie poniższe stwierdzenia są prawdziwe:
Jeśli porównasz lokalizację kasy (która sama w sobie jest repozytorium z Git), historia będzie zupełnie inna:
Jeśli porównasz liczbę bajtów, które musisz pobrać lub przesłać, znowu będzie inaczej.
Na koniec porównujesz jabłka z pomarańczami i w zależności od tego, co chcesz zrobić z Subversion lub Git, wynik może być inny.
@jk zapytał o kompletne kopie lub różnice binarne i nie mogłem odpowiedzieć na to pytanie. Zapytałem Matthew McCullougha, który ostatnio przeprowadził warsztaty Git na Jax 2012 (który odwiedziłem). Poświęcił czas (dziękuję mu bardzo), aby wyjaśnić ze szczegółową istotą wewnętrzne działanie Git. Więc tak, działa tam kompresja (i ja też przeprowadzę eksperyment z plikiem biurowym Microsoft i porównam go z jego treścią), ale nie, kompresja jest wykonywana dla całego pliku. Powołując się na swoją treść:
źródło
git gc
lub nagromadzenie zbyt wielu luźnych obiektów, znajdzie dobrych kandydatów do skompresowania ich w delcie (git może różnić się w stosunku do innej niż poprzednia wersja), przechowuje delty w „paczce” i usuwa luźne obiekty.