Zagmatwany bit jest tutaj:
Git nigdy nie postrzega tych plików jako pojedynczych plików. Git uważa wszystko za pełną treść.
Git często używa 160-bitowych skrótów zamiast obiektów we własnym repozytorium. Drzewo plików to w zasadzie lista nazw i skrótów powiązanych z zawartością każdego z nich (plus niektóre metadane).
Ale 160-bitowy skrót jednoznacznie identyfikuje treść (we wszechświecie bazy danych git). Zatem drzewo z skrótami jako treść zawiera zawartość w jej stanie.
Jeśli zmienisz stan zawartości pliku, zmieni się jego skrót. Ale jeśli zmieni się jego skrót, zmieni się również skrót związany z zawartością nazwy pliku. Co z kolei zmienia skrót „drzewa katalogów”.
Gdy baza danych git przechowuje drzewo katalogów, drzewo to implikuje i zawiera całą zawartość wszystkich podkatalogów i wszystkich plików w nim zawartych .
Jest on zorganizowany w strukturę drzewa z (niezmiennymi, wielokrotnego użytku) wskaźnikami do obiektów blob lub innych drzew, ale logicznie jest to pojedyncza migawka całej zawartości całego drzewa. Reprezentacja w bazie git nie jest płaskie treść danych, ale logicznie to wszystko jego dane i nic innego.
Jeśli serializujesz drzewo do systemu plików, usuwasz wszystkie foldery .git i każesz gitowi dodać drzewo z powrotem do swojej bazy danych, skończysz na tym, że nic nie dodasz do bazy danych - element już tam będzie.
Pomóc może myśleć o skrótach gita jako o wskaźniku liczonym jako odniesienie do niezmiennych danych.
Jeśli stworzysz wokół niego aplikację, dokument to wiązka stron, które mają warstwy, grupy, obiekty.
Kiedy chcesz zmienić obiekt, musisz utworzyć dla niego zupełnie nową grupę. Jeśli chcesz zmienić grupę, musisz utworzyć nową warstwę, która potrzebuje nowej strony, która potrzebuje nowego dokumentu.
Za każdym razem, gdy zmieniasz pojedynczy obiekt, odradza się nowy dokument. Stary dokument nadal istnieje. Nowy i stary dokument udostępniają większość swoich treści - mają te same strony (oprócz 1). Ta jedna strona ma te same warstwy (oprócz 1). Ta warstwa ma te same grupy (oprócz 1). Ta grupa ma te same obiekty (oprócz 1).
I przez to rozumiem logicznie kopię, ale pod względem implementacji jest to po prostu kolejny wskaźnik zliczany referencją do tego samego niezmiennego obiektu.
Git repo jest bardzo podobny.
Oznacza to, że dany zestaw zmian git zawiera komunikat zatwierdzenia (jako kod skrótu), zawiera drzewo pracy i zawiera zmiany nadrzędne.
Te zmiany nadrzędne zawierają zmiany nadrzędne od samego początku.
Częścią repozytorium git, która zawiera historię, jest łańcuch zmian. Ten łańcuch zmian zmienia go na poziomie powyżej drzewa „katalogu” - z drzewa „katalogu” nie można jednoznacznie dostać się do zestawu zmian i łańcucha zmian.
Aby dowiedzieć się, co dzieje się z plikiem, zaczynasz od tego pliku w zestawie zmian. Ten zestaw zmian ma swoją historię. Często w tej historii istnieje ten sam nazwany plik, czasem o tej samej treści. Jeśli treść jest taka sama, nie było zmian w pliku. Jeśli jest inaczej, następuje zmiana i należy wykonać pracę, aby dokładnie ustalić, co.
Czasami plik zniknął; ale drzewo „katalogu” może mieć inny plik z tą samą zawartością (ten sam kod skrótu), więc możemy to prześledzić w ten sposób (uwaga; właśnie dlatego chcesz, aby zatwierdzenie przesunęło plik osobno od zatwierdzenia do -edytować). Lub ta sama nazwa pliku, a po sprawdzeniu plik jest wystarczająco podobny.
Git może więc łączyć „historię plików”.
Ale ta historia plików pochodzi z wydajnego analizowania „całego zestawu zmian”, a nie z łącza z jednej wersji pliku do innej.