Jak git przechowuje pliki?

225

Właśnie zacząłem uczyć się git i aby to zrobić, zacząłem czytać Git Community Book , aw tej książce mówią, że SVN i CVS przechowują różnicę między plikami, a git przechowuje migawkę wszystkich plików.

Ale tak naprawdę nie zrozumiałem, co rozumieją przez migawkę. Czy git naprawdę robi kopię wszystkich plików w każdym zatwierdzeniu, ponieważ to zrozumiałem z ich wyjaśnienia.

PS: Jeśli ktokolwiek ma lepsze źródło nauki git, byłbym wdzięczny.

mteffaha
źródło
20
Oto genialny post, który szczegółowo wyjaśnia, jak działa git. To, czego szukasz, to prawdopodobnie § o bazie danych obiektów.
greg0ire,
Doskonały artykuł, który zawiera linki do innych świetnych zasobów. Bawiłem się nimi przez kilka godzin.
mihai
2
Znalazłem ten naprawdę fajny artykuł opisujący gita od wewnątrz: maryrosecook.com/blog/post/git-from-the-inside-out
Sumudu

Odpowiedzi:

275

Git zawiera dla każdego zatwierdzenia pełną kopię wszystkich plików, z tym wyjątkiem, że w przypadku treści już znajdującej się w repozytorium Git migawka będzie po prostu wskazywała na tę treść, a nie powielała ją.
Oznacza to również, że kilka plików o tej samej zawartości jest przechowywanych tylko raz.

Tak więc migawka jest w zasadzie zatwierdzeniem, odnoszącym się do zawartości struktury katalogów.

Niektóre dobre referencje to:

Mówisz Gitowi, że chcesz zapisać migawkę swojego projektu za pomocą polecenia git commit i rejestruje on w zasadzie manifestację tego, jak w tym momencie wyglądają wszystkie pliki twojego projektu

Ćwiczenie 12 ilustruje, jak uzyskać poprzednie migawki


Książka progit ma pełniejszy opis migawka:

Główną różnicą między Git a innymi VCS (w tym Subversion i przyjaciółmi) jest sposób, w jaki Git myśli o swoich danych.
Pod względem koncepcyjnym większość innych systemów przechowuje informacje jako listę zmian opartych na plikach. Te systemy (CVS, Subversion, Perforce, Bazaar itd.) Myślą o przechowywanych informacjach jako zestawie plików oraz o zmianach wprowadzanych w każdym pliku w czasie

VCS oparty na delcie

Git nie myśli ani nie przechowuje swoich danych w ten sposób. Zamiast tego Git myśli o swoich danych bardziej jak o zestawie migawek mini systemu plików.
Za każdym razem, gdy zatwierdzasz lub zapisujesz stan swojego projektu w Git, zasadniczo robi zdjęcie, jak wyglądają wszystkie twoje pliki w tym momencie i przechowuje odniesienie do tej migawki.
Aby być wydajnym, jeśli pliki się nie zmieniły, Git nie przechowuje pliku ponownie - tylko link do poprzedniego identycznego pliku, który już zapisał.
Git myśli o swoich danych bardziej jak poniżej:

VCS oparte na migawkach

Jest to ważne rozróżnienie między Git i prawie wszystkimi innymi VCS. To sprawia, że ​​Git ponownie rozważa prawie każdy aspekt kontroli wersji, który większość innych systemów skopiowała z poprzedniej generacji. To sprawia, że ​​Git przypomina bardziej mini-system plików z kilkoma niesamowicie potężnymi narzędziami zbudowanymi na nim, a nie tylko VCS.


Jan Hudec dodaje ten ważny komentarz :

Chociaż jest to prawda i ważne na poziomie koncepcyjnym, NIE jest to prawda na poziomie pamięci.
Git używa do przechowywania delt .
Nie tylko to, ale jest bardziej wydajne niż jakikolwiek inny system. Ponieważ nie zachowuje historii poszczególnych plików, gdy chce wykonać kompresję delta, pobiera każdy obiekt blob, wybiera niektóre obiekty blob, które prawdopodobnie będą podobne (przy użyciu heurystyki, która obejmuje najbliższe przybliżenie poprzedniej wersji i niektórych innych), próbuje wygenerować delty i wybiera najmniejszą. W ten sposób może (często w zależności od heurystyki) korzystać z innych podobnych plików lub starszych wersji, które są bardziej podobne do poprzednich. Parametr „okna pakietu” umożliwia wydajność handlową dla jakości kompresji delta. Wartość domyślna (10) zazwyczaj daje przyzwoite wyniki, ale gdy ilość miejsca jest ograniczona lub w celu przyspieszenia transferów sieciowych, git gc --aggressiveużywa wartości 250, co powoduje, że działa bardzo wolno, ale zapewnia dodatkową kompresję danych historycznych.

VonC
źródło
4
@JanHudec dobry punkt. W odpowiedzi umieściłem twój komentarz dla większej widoczności.
VonC
1
Czy ktoś zna termin informatyki na wzór przechowywania podobny do Git, zwany także hashowym sklepem wartości? (lub coś podobnego)
Joannes Vermorel
34
W kontekście rzeczywistego pytania PO pierwszy akapit wydaje się bardzo mylący. To nie jest aż dojdziesz do ostatniego ustępu, dowiadujemy się, że, och tak, fakt Git robi „sklep [...] różnice między plikami. Naprawdę szkoda że informacji został oflagowany się szczyt i nie pogrzebane tak głęboko. To powiedziawszy, dzięki w najmniej w tym prawdziwą historię gdzieś w swojej odpowiedzi;)
Josh O'Brien
1
@NickVolynkin Świetnie! Cieszę się, że te odpowiedzi znajdują większą grupę odbiorców.
VCC,
1
Kolejna dobra książka: Git From The Bottom Up: ftp.newartisans.com/pub/git.from.bottom.up.pdf
Jonas Berlin
46

Git logicznie przechowuje każdy plik pod SHA1. Oznacza to, że jeśli masz dwa pliki o dokładnie takiej samej zawartości w repozytorium (lub jeśli zmienisz nazwę pliku), przechowywana jest tylko jedna kopia.

Ale oznacza to również, że po zmodyfikowaniu małej części pliku i zatwierdzeniu zapisywana jest kolejna kopia pliku. Sposób, w jaki git to rozwiązuje, polega na użyciu plików paczek. Raz na jakiś czas wszystkie „luźne” pliki (w rzeczywistości nie tylko pliki, ale także obiekty zawierające informacje o zatwierdzeniu i katalogu) z repozytorium są gromadzone i kompresowane do pliku paczki. Plik paczki jest kompresowany za pomocą zlib. Podobne pliki są również kompresowane w delcie.

Ten sam format jest również używany podczas ciągnięcia lub wypychania (przynajmniej w przypadku niektórych protokołów), więc te pliki nie muszą być ponownie kompresowane.

Powoduje to, że repozytorium git, zawierające całą nieskompresowaną kopię roboczą, nieskompresowane najnowsze pliki i skompresowane starsze pliki, jest zwykle stosunkowo małe, dwa razy mniejsze niż rozmiar kopii roboczej. A to oznacza, że ​​jest mniejszy niż repozytorium SVN z tymi samymi plikami, mimo że SVN nie przechowuje historii lokalnie.

svick
źródło
1
och, więc rtęć jest bardziej efektywny pod względem przestrzeni
Ben