Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 13 - Git - Vnitřní struktura

V předchozím kvízu, Kvíz - Kolize mezi větvemi a vzdálený repositář v Gitu, jsme si ověřili nabyté zkušenosti z předchozích lekcí.

V dnešním Git tutoriálu se podíváme na vnitřní strukturu Gitu. Ponoříme se do detailů způsobu úschovy commitů a vykonávaných změn v souborech provedených Gitem. Také si vysvětlíme k čemu slouží složka .git/.

Zase si všechny příkazy budeme zkoušet v našem naklonovaném repositáři Laravel z lekce Git - Základy - Dokončení. Otevřeme terminál MinTTY a pomocí příkazu cd laravel se do repositáře přesuneme.

Vnitřní struktura Gitu

Git funguje jako tabulka mapující hodnoty (náš obsah) pomocí unikátních klíčů. Každá hodnota je posloupností bajtů. Přiřazením hodnoty vytvoří Git hashovací klíč pomocí kontrolního součtu SHA-1. Hashovací klíč slouží k identifikaci uložených hodnot bez ohledu na počítačovou platformu či operační systém. Jestliže se hodnota nemění, Git vždy poskytne stejný hash klíč.

Pro každý soubor Git počítá kontrolní součet SHA-1 v podobě 40-ti místného hexadecimálního čísla, podle kterého si Git soubor ukládá.

Představme si, že chceme verzovat složku s několika soubory a podsložkami. Naivním řešením by bylo u každé nové verze překopírovat celý její obsah a tak zpětně skládat různé verze. To by bylo velmi neefektivní řešení. Navíc verze každého souboru by měla být jednoznačně identifikovatelná, abychom mohli verze různě kombinovat.

Vnitřní struktura Gitu se skládá z:

  • BLOB objektů – uchovávají obsah jednotlivých souborů,
  • Tree objektů – slouží k reprezentaci struktury složek a obsahují odkazy na BLOB objekty nebo další stromy,
  • Commitů – zaznamenávají metadata, jako je autor, popis změn a odkazy na konkrétní stromy (tree objekty),
  • Ukazatelů na commity – pomocí nich se definují vztahy mezi commity a větvemi v historii,
  • Tagů – označují specifické commity nebo body v historii.

Ukažme si, jak jsou objekty ve vnitřní struktuře Gitu na sebe navzájem navázány:

Git

Commity, Tagy, BLOB- a Tree objekty jsou identifikovány pomocí šifry SHA-1, která zajišťuje jejich jedinečnost. V počátečních verzích Gitu bylo nutné tuto strukturu vytvářet ručně. Dnes Git tento proces automatizuje a uživatelé využívají příkazy k manipulaci se strukturou. I přesto se podíváme na základní principy, jak Git uvnitř pracuje, abychom lépe porozuměli jeho fungování.

Složka .git/

Při inicializaci nového úložiště pomocí příkazu git init, Git vytvoří složku .git/ s několika soubory a podsložkami. Jelikož jsme repositář Laravel klonovali, složku .git/ již obsahuje. Přesuňme se do ní pomocí příkazu cd .git:

MINGW64:/c/mujgit/laravel
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel (10.x)
$ cd .git
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git (GIT_DIR!)
$

Následně příkazem ls získejme výpis jejího obsahu:

MINGW64:/c/mujgit/laravel/.git
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git (GIT_DIR!)
$ ls
COMMIT_EDITMSG  ORIG_HEAD  description  index  logs/     packed-refs
HEAD            config     hooks/       info/  objects/  refs/
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git (GIT_DIR!)
$

Tento výpis zobrazuje seznam souborů a složek ve složce .git/, které jsou součástí základní struktury vytvořené při inicializaci úložiště Git.

Samotné soubory ve složce .git/ mají specifické účely a zastávají důležité role při uchovávání informací o stavu repositáře a jeho historie. Složka .git/ obsahuje soubory a složky:

  • HEAD – odkazuje na aktuální referenční bod v repositáři, aktuální větev (branch) nebo na konkrétní commit,
  • description – obsahuje textový popis repositáře,
  • index – uchovává informace o stavu pracovní složky a staging oblasti,
  • logs/ – obsahuje historii událostí v repositáři,
  • packed-refs – obsahuje seznam zabalovaných referencí, typicky odkazy na konkrétní commity,
  • config – uchovává konfiguraci repositáře,
  • hooks/ – obsahuje spouštěcí skripty pro různé události,
  • info/ – obsahuje různé informace o repositáři,
  • objects/ – uchovává všechny objekty v repositáři,
  • refs/ – obsahuje odkazy na commity a větve,
  • COMMIT_EDITMSG – obsahuje zprávy commitů,
  • ORIG_HEAD – ukládá stav hlavy před provedením operace změny.

Nyní si blíže popíšeme složky objects/, info/, logs/.

Složka objects/

Složka objects/ je databáze objektů Gitu, v nichž jsou uloženy všechny potřebné objekty pro uchování různých verzí našeho projektu. Přesuňme se nyní do této složky příkazem cd objects/ a získejme její obsah příkazem ls:

MINGW64:/c/mujgit/laravel/.git/objects
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git (GIT_DIR!)
$ cd objects
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/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/
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects (GIT_DIR!)
$

Nyní se na jednotlivé typy podsložek složky objects/ podíváme podrobněji.

Složky info/ a pack/

Složky info/ a pack/ jsou využívány Gitem pro provádění nízko-úrovňových optimalizací a manipulaci s objekty. Složka:

  • info/ – ukládá nezabalované objekty, obsahuje metadata a další informace o objektech v repositáři,
  • pack/ – ukládá zabalované objekty, čímž zlepšuje efektivitu úložiště a urychluje operace v repositáři Git.
Složky s číselnými názvy

Tyto podsložky ve složce objects/ označují shluky objektů v repositáři Gitu. Pojďme se ponořit do těchto objektů a podívat se, co přesně jsou zač. Začneme tím, že se podíváme na poslední commit. Zadáme příkaz git log, kterým získáme poslední provedený commit včetně jeho hashe:

MINGW64:/c/mujgit/laravel/.git/objects
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects (GIT_DIR!)
$ git log
commit 61f09d5980757dc0a9c05570d24584714b7cd635 (HEAD -> 10.x)
Merge: 700444ac 53c4ef4e
Author: itnetwork <[email protected]>
Date:   Wed Aug 30 10:42:37 2023 +0200

    Oprava kolize při sloučení větví
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects (GIT_DIR!)
$

Vidíme, že hash commitu je 61f09d5980757dc0a9c05570d24584714b7cd635. Opět spustíme příkaz ls, abychom zobrazili obsah složky objects/:

MINGW64:/c/mujgit/laravel/.git/objects
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/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/
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects (GIT_DIR!)
$

Když porovnáme první dvě cifry commitu s názvy složek zjistíme, že tato složka má tyto cifry stejné s tímto hashem commitu:

Hash: 61f09d5980757dc0a9c05570d24584714b7cd635
Složka: 61/

Příkazem cd 61 se tedy přesuňme do této složky a zobrazme příkazem ls její obsah:

MINGW64:/c/mujgit/laravel/.git/objects/61
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects (GIT_DIR!)
$ cd 61
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects/61 (GIT_DIR!)
$ ls
f09d5980757dc0a9c05570d24584714b7cd635
ItNetwork@DESKTOP-ADEVTG4 MINGW64 /c/mujgit/laravel/.git/objects/61 (GIT_DIR!)
$

Vidíme, že je zde soubor, který obsahuje zbytek našeho hashe. Název souboru se rovná zbytku znaků, které tvoří hash klíč commitu. Tohle označení složek a souborů v databázi objektů je konvence, kterou Git dodržuje pro efektivní vyhledávání objektů. V tomto případě se jedná o objekt v databázi objektů pro tento commit. …

Složka logs/

Vrátíme se do složky .git/, kde nalezneme složku logs/. Ta obsahuje historii událostí v repositáři. Tato složka uchovává různé záznamy a logy související s pohybem referencí, jako jsou větve (branches) a reflogy. Reflogy jsou záznamy o pohybu referencí včetně informací o posledních změnách, například změnách větví nebo obnovení ztracených commitů.

Každá změna v referencích, jako je přesunutí větve nebo změna historie commitů, je zaznamenána v této složce. Logy v této složce jsou uchovávány pro sledování a možnost obnovy historie změn a operací v repositáři.

Složka logs/ obsahuje různé podsložky a soubory pro různé typy logů a záznamů, které poskytují informace o pohybu v repositáři. Uchovávání těchto záznamů umožňuje vývojářům analyzovat historii změn a provádět operace obnovy.

Složka info/

Ve složce .git/ nalezneme také složku info/, která obsahuje různé informace o repositáři. Tato složka slouží k uchování různých konfiguračních a informačních souborů, které poskytují metadata a další užitečné údaje pro Git repositář.

Ve složce info/ můžeme najít tyto soubory:

  • exclude – obsahuje pravidla pro ignorování souborů a složek v rámci repositáře, podobně jako soubor .gitignore,
  • grafts – uchovává informace o historických bodech spojování commitů, tak zvaných graft points, a to v případě změny historie větví,
  • attributes – obsahuje specifické nastavení pro různé typy souborů, jako jsou atributy ovlivňující chování Gitu při práci se soubory.

V příští lekci, Git - Vnitřní struktura - Dokončení, detailněji prozkoumáme objekty typu blob, tree, commit a tag. Také si vysvětlíme, jak Git uchovává názvy souborů.


 

Předchozí článek
Kvíz - Kolize mezi větvemi a vzdálený repositář v Gitu
Všechny články v sekci
Git
Přeskočit článek
(nedoporučujeme)
Git - Vnitřní struktura - Dokončení
Článek pro vás napsala Simona Raučinová
Avatar
Uživatelské hodnocení:
39 hlasů
Aktivity