13. diel - Git - Vnútorná štruktúra
V predchádzajúcom kvíze, Kvíz - Kolízie medzi vetvami a vzdialený repositár v Gitu, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.
V dnešnom Git tutoriále 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/
.
Zase si všetky príkazy budeme skúšať v našom naklonovanom
repositári Laravel z lekcie Git – Základy –
Dokončenie. Otvoríme terminál MinTTY
a pomocou príkazu
cd laravel
sa do repositára presunieme.
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 verzia každého súboru by mala byť 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ú príkazy na manipuláciu so štruktúrou. 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 repositá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 repositára a
jeho histórie. Priečinok .git/
obsahuje súbory a priečinky:
HEAD
– odkazuje na aktuálny referenčný bod v repositári, aktuálnu vetvu (branch) alebo na konkrétny commit,description
– obsahuje textový popis repositára,index
– uchováva informácie o stave pracovnej zložky a staging oblasti,logs/
– obsahuje históriu udalostí v repositári,packed-refs
– obsahuje zoznam zabaľovaných referencií, typicky odkazy na konkrétne commity,config
– uchováva konfiguráciu repositára,hooks/
– obsahuje spúšťacie skripty pre rôzne udalosti,info/
– obsahuje rôzne informácie o repositári,objects/
– uchováva všetky objekty v repositá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 pre 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/
sú využívané Gitom 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 repositári,pack/
– ukladá zabaľované objekty, čím zlepšuje efektivitu úložiska a urýchľuje operácie v repositári Git.
Zložky s číselnými názvami
Tieto podpriečinky v priečinku objects/
označujú zhluky
objektov v repositári Gitu. Poďme sa ponoriť do týchto objektov a pozrieť
sa, čo presne 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 hasha:
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á tieto cifry rovnaké s týmto hashom commitu:
Hash: 61f09d5980757dc0a9c05570d24584714b7cd635 Directory: 61/
Príkazom cd 61
sa teda presuňme do tohto priečinka a zobrazme
príkazom ls
jej 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 hasha. 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žuje 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
repositá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 repositá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
repositá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 repositá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 repositá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 repositá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 budúcej 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.