13. diel - Git - Vnútorná štruktúra
V predchádzajúcom kvíze, Kvíz - Kolízie medzi vetvami a vzdialený repozitár v Gite, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.
V dnešnom tutoriáli Git sa pozrieme na vnútornú
štruktúru Gitu. Ponoríme sa do detailov spôsobu úschovy commitov a
vykonávaných zmien v súboroch vykonaných Gitom. Tiež si vysvetlíme, na čo
slúži zložka .git/.
Všetky príkazy si budeme znova skúšať v našom naklonovanom
repozitári Laravel z lekcie Git – Základy –
Dokončenie. Otvoríme terminál MinTTY a pomocou príkazu
cd laravel sa presunieme do repozitára.
Vnútorná štruktúra Gitu
Git funguje ako tabuľka mapujúca hodnoty (náš obsah) pomocou unikátnych kľúčov. Každá hodnota je postupnosťou bajtov. Priradením hodnoty vytvorí Git hashovací kľúč pomocou kontrolného súčtu SHA-1. Hashovací kľúč slúži na identifikáciu uložených hodnôt bez ohľadu na počítačovú platformu či operačný systém. Ak sa hodnota nemení, Git vždy poskytne rovnaký hash kľúč.
Pre každý súbor Git počíta kontrolný súčet SHA-1 v podobe 40-miestneho hexadecimálneho čísla, podľa ktorého si Git súbor ukladá.
Predstavme si, že chceme verzovať zložku s niekoľkými súbormi a podpriečinkami. Naivným riešením by bolo pri každej novej verzii prekopírovať celý jej obsah a tak spätne skladať rôzne verzie. To by bolo veľmi neefektívne riešenie. Navyše by mala byť verzia každého súboru jednoznačne identifikovateľná, aby sme mohli verzie rôzne kombinovať.
Vnútorná štruktúra Gitu sa skladá z:
- BLOB objektov – uchovávajú obsah jednotlivých súborov,
- Tree objektov – slúžia na reprezentáciu štruktúry zložiek a obsahujú odkazy na BLOB objekty alebo ďalšie stromy,
- Commitov – zaznamenávajú metadáta, ako je autor, popis zmien a odkazy na konkrétne stromy (tree objekty),
- Ukazovateľov na commity – pomocou nich sa definujú vzťahy medzi commitmi a vetvami v histórii,
- Tagov – označujú špecifické commity alebo body v histórii.
Ukážme si, ako sú objekty vo vnútornej štruktúre Gitu na seba navzájom naviazané:
Commity, tagy, BLOB a tree objekty sú identifikované pomocou šifry SHA-1, ktorá zaisťuje ich jedinečnosť. V počiatočných verziách Gitu bolo nutné túto štruktúru vytvárať ručne. Dnes Git tento proces automatizuje a používatelia využívajú na manipuláciu so štruktúrou príkazy. Aj napriek tomu sa pozrieme na základné princípy, ako Git vo vnútri pracuje, aby sme lepšie porozumeli jeho fungovaniu.
Zložka .git/
Pri inicializácii nového úložiska pomocou príkazu git init,
Git vytvorí zložku .git/ s niekoľkými súbormi a
podpriečinkami. Keďže sme repozitár Laravel klonovali, zložku
.git/ už obsahuje. Presuňme sa do nej pomocou príkazu
cd .git:
MINGW64:/c/mygit/laravel IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel (10.x) $ cd .git IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git (GIT_DIR!) $
Následne príkazom ls získajme výpis jej obsahu:
MINGW64:/c/mygit/laravel/.git IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git (GIT_DIR!) $ ls COMMIT_EDITMSG ORIG_HEAD description index logs/ packed-refs HEAD config hooks/ info/ objects/ refs/ IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git (GIT_DIR!) $
Tento výpis zobrazuje zoznam súborov a priečinkov v priečinku
.git/, ktoré sú súčasťou základnej štruktúry vytvorenej pri
inicializácii úložiska Git.
Samotné súbory v priečinku .git/ majú špecifické účely a
zastávajú dôležité role pri uchovávaní informácií o stave repozitára a
jeho histórie. Priečinok .git/ obsahuje súbory a priečinky:
HEAD– odkazuje na aktuálny referenčný bod v repozitári, aktuálnu vetvu (branch) alebo na konkrétny commit,description– obsahuje textový popis repozitára,index– uchováva informácie o stave pracovnej zložky a staging oblasti,logs/– obsahuje históriu udalostí v repozitári,packed-refs– obsahuje zoznam zabaľovaných referencií, typicky odkazy na konkrétne commity,config– uchováva konfiguráciu repozitára,hooks/– obsahuje spúšťacie skripty pre rôzne udalosti,info/– obsahuje rôzne informácie o repozitári,objects/– uchováva všetky objekty v repozitári,refs/– obsahuje odkazy na commity a vetvy,COMMIT_EDITMSG– obsahuje správy commitov,ORIG_HEAD– ukladá stav hlavy pred vykonaním operácie zmeny.
Teraz si bližšie popíšeme zložky objects/,
info/, logs/.
Zložka objects/
Priečinok objects/ je databáza objektov Gitu,
v ktorých sú uložené všetky potrebné objekty na uchovanie rôznych verzií
nášho projektu. Presuňme sa teraz do tejto zložky príkazom
cd objects/ a získajme jej obsah príkazom ls:
MINGW64:/c/mygit/laravel/.git/objects IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git (GIT_DIR!) $ cd objects IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $ ls 04/ 18/ 2c/ 30/ 51/ 5c/ 65/ 6e/ 7b/ 85/ a9/ ac/ b5/ c4/ info/ 16/ 29/ 2e/ 39/ 53/ 61/ 67/ 70/ 81/ a2/ aa/ ae/ c0/ ca/ pack/ IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $
Teraz sa na jednotlivé typy podpriečinkov zložky objects/
pozrieme podrobnejšie.
Zložky info/ a
pack/
Zložky info/ a pack/ Git využíva na vykonávanie
nízkoúrovňových optimalizácií a manipuláciu s
objektmi. Zložka:
info/– ukladá nezabaľované objekty, obsahuje metadáta a ďalšie informácie o objektoch v repozitári,pack/– ukladá zabaľované objekty, čím zlepšuje efektivitu úložiska a urýchľuje operácie v repozitári Git.
Zložky s číselnými názvami
Tieto podpriečinky v priečinku objects/ označujú zhluky
objektov v repozitári Gitu. Poďme sa zamerať na tieto objekty a pozrieť sa,
čo sú zač. Začneme tým, že sa pozrieme na posledný commit. Zadáme
príkaz git log, ktorým získame posledný uskutočnený commit
vrátane jeho hashu:
MINGW64:/c/mygit/laravel/.git/objects IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $ git log commit 61f09d5980757dc0a9c05570d24584714b7cd635 (HEAD -> 10.x) Merge: 700444ac 53c4ef4e Author: ictdemy <[email protected]> Date: Wed Aug 30 10:42:37 2023 +0200 Fix collision when merging branches IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $
Vidíme, že hash commitu je
61f09d5980757dc0a9c05570d24584714b7cd635. Opäť spustíme príkaz
ls, aby sme zobrazili obsah zložky objects/:
MINGW64:/c/mygit/laravel/.git/objects IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $ ls 04/ 18/ 2c/ 30/ 51/ 5c/ 65/ 6e/ 7b/ 85/ a9/ ac/ b5/ c4/ info/ 16/ 29/ 2e/ 39/ 53/ 61/ 67/ 70/ 81/ a2/ aa/ ae/ c0/ ca/ pack/ IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $
Keď porovnáme prvé dve cifry commitu s názvami zložiek, zistíme, že táto zložka má rovnaké cifry ako tento hash commit:
Hash: 61f09d5980757dc0a9c05570d24584714b7cd635 Directory: 61/
Príkazom cd 61 sa teda presuňme do tohto priečinka a
príkazom ls zobrazme jeho obsah:
MINGW64:/c/mygit/laravel/.git/objects/61 IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects (GIT_DIR!) $ cd 61 IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects/61 (GIT_DIR!) $ ls f09d5980757dc0a9c05570d24584714b7cd635 IctDemy@DESKTOP-ADEVTG4 MINGW64 /c/mygit/laravel/.git/objects/61 (GIT_DIR!) $
Vidíme, že je tu súbor, ktorý obsahuje zvyšok nášho hashu. Názov súboru sa rovná zvyšku znakov, ktoré tvoria hash kľúč commitu. Toto označenie zložiek a súborov v databáze objektov je konvencia, ktorú Git dodržiava pre efektívne vyhľadávanie objektov. V tomto prípade ide o objekt v databáze objektov pre tento commit.
Zložka logs/
Vrátime sa do zložky .git/, kde nájdeme zložku
logs/. Tá obsahuje históriu udalostí v
repozitári. Táto zložka uchováva rôzne záznamy a logy súvisiace s pohybom
referencií, ako sú vetvy (branches) a reflogy. Reflogy sú
záznamy o pohybe referencií vrátane informácií o posledných zmenách,
napríklad zmenách vetiev alebo obnovení stratených commitov.
Každá zmena v referenciách, ako je presunutie vetvy alebo zmena histórie commitov, je zaznamenaná v tejto zložke. Logy v tejto zložke sú uchovávané pre sledovanie a možnosť obnovy histórie zmien a operácií v repozitári.
Priečinok logs/ obsahuje rôzne podpriečinky a súbory pre
rôzne typy logov a záznamov, ktoré poskytujú informácie o pohybe v
repozitári. Uchovávanie týchto záznamov umožňuje vývojárom
analyzovať históriu zmien a vykonávať operácie
obnovy.
Zložka info/
V zložke .git/ nájdeme aj zložku info/, ktorá
obsahuje rôzne informácie o repozitári. Táto zložka slúži na uchovanie
rôznych konfiguračných a informačných súborov, ktoré poskytujú metadáta
a ďalšie užitočné údaje pre Git repozitár.
V priečinku info/ môžeme nájsť tieto súbory:
exclude– obsahuje pravidlá pre ignorovanie súborov a zložiek v rámci repozitára, podobne ako súbor.gitignore,grafts– uchováva informácie o historických bodoch spájania commitov, takzvaných graft points, a to v prípade zmeny histórie vetiev,attributes– obsahuje špecifické nastavenia pre rôzne typy súborov, ako sú atribúty ovplyvňujúce správanie Gitu pri práci so súbormi.
V ďalšej lekcii, Git - Vnútorná štruktúra - Dokončenie, detailnejšie preskúmame objekty typu
blob, tree, commit a tag.
Tiež si vysvetlíme, ako Git uchováva názvy súborov.

