I když si základní příkazy GITu uvedeme později, pro počáteční studium je vhodné si vytvořit nějaký repositář. Ideálně klon nějakého již existujícího (musíte znát jeho URI). To se provede pomocí příkazu:
$ git clone <uri>
a nebo si vytvořte nový prázdný pomocí:
$ mkdir myproject $ cd myproject $ git init
Repositář není nic jiného než adresář .git
plný souborů. Lze jej tedy zpřístupnit pomocí http, ssh, rsync apod. (Případně git implementuje vlastní metodu pomocí git-daemona). Existují i různá GTK, KDE, a Web GUI.
GIT repositář se skládá ze tří částí.
- working directory – místo kde se provádí změny
- index – mezivrstva sloužící jako cache mezi DB objektů a pracovním adresářem.
- object DB – vlastní data
Jak je zřejmé, jádrem repositáře je databáze objektů. Platí, že každý objekt je adresován SHA-1 kontrolním součtem obsahu daného objektu. GIT interně nepracuje se jmény souborů. GIT rozlišuje tři základní objekty:
- blob – obsahuje data souboru
- tree – je seznam blobů a podstromů
- commit – je spojením mezi tree a jeho rodičem a obsahuje další informace o commitu (komentář, kdo, kdy apod.)
Na tomto místě je důležité říci, že GIT interně neuchovává pouze změny (diff), ale celé soubory. Uděláte-li změnu v nějakém souboru, je celý soubor uložen jako komprimovaný do repositáře v podobě blob objektu. Commit je pak snapshot (tree) obsahující všechny soubory. Pochopitelně pokud se soubor neměnil, je stejné i jeho SHA-1 a je sdílen mezi různými stromy (tree).
Je-li třeba rozdíl (diff) mezi dvěma verzemi, pouze se porovnají blob objekty daných verzí. Podobně pokud se chcete vrátit v pracovním adresáři do stavu, který panoval u nějakého dřívějšího commitu, tak se daný commit nalezne (zadáte například jeho SHA-1) v repositáři. Commit ukazuje na tree, který, jak bylo řečeno, je seznamem blobů. Tyto bloby se nakopírují do vašeho pracovního adresáře. Podobně dělá GIT většinu operací. Nepracuje s diff jednotlivých verzí. Výhodou je obrovská rychlost a nezávislost na jménech souborů (není zde problém s přejmenováním souborů). Nevýhodou je větší náročnost na diskový prostor (ten je ale daleko levnější než čas vývojáře).
GIT ještě interně podporuje tzv. „pack files“. Jedná se o do jednoho souboru zabalené object soubory. Použití je primárně na veřejných repositářích, kde se tímto způsobem zvyšuje efektivita downloadu (více viz man git-repack).
Takto navržený repositář umožňuje velmi snadno a efektivně uchovávat informace o větvení projektu na samostatné větve. Větev není nic jiného, než že se obsah repositáře rozdělí na dále již samostatně se vyvíjející větve. S tím, že každá taková větev je nějak pojmenována. Pojmenování znamená samozřejmě, že se nějakému SHA-1, které ukazuje na nějaký v repositáři uložený objekt (commit), přiřadí jméno. Jinými slovy – vytvoří se reference.
Defaultní větev je „master“. GIT si ale udržuje interně i další (například origin/master apod.), více informaci dostanete příkazem:
$ git branch -a
Reference nemusí být jen název větve, ale taktéž tzv. tag. Například
$ git tag "RELEASE_0.1"
pojmenuje poslední commit jménem „RELEASE0.1“. Toto jméno pak lze používat ve většině příkazů GITu namísto SHA-1.
Standardní referencí je tzv. HEAD – poslední commit aktuální větve. Ten je použit, neuvedete-li nic jiného. Pro hlubší zkoumání doporučuji adresář .git/refs/
, kde jsou všechny reference uloženy jako soubory obsahující SHA-1, na která dané jméno odkazuje. Například:
$ cat .git/refs/heads/master 628cab7cde49bfb0387a51d5390d65921d7c3dc4
Další vestavěnou referencí je ORIG_HEAD, který odkazuje na HEAD před příkazem git-reset
. Například příkazy:
$ git reset HEAD^ $ git commit -a -c ORIG_HEAD
vrátí repositář do stavu před posledním commitem (ale pracovní adresář ponechá nedotčený) a provede nový commit. Jako commit message (komentář patche) použije komentář z resetovaného patche.
Pozorný čtenář určitě přemýšlí co je to ^
u příkazu git-reset
. Jedná se o další způsob odkazu (reference) na objekt. Pro úplnost vyjmenujme všechny základní způsoby, jak se odkazovat v GITu:
- SHA-1 – checksum objektu, 40 hex číslic, ale lze použít i jen fragment z SHA-1
- tag – pro lidi čitelné pojmenování
- HEAD – odkazuje na vrchol aktuální větve
- commit^n – odkazuje na ‚n‘ rodiče commitu
- commit~n – odkazuje na ‚n‘ generaci pra-rodiče, následuje vždy jen prvního rodiče (pozn. u spojení větví může vzniknout víc než jeden rodič.)
- ref@{date} – odkazuje na datum před referencí ‚ref‘
- :/text – commit kde commit message začíná ‚text‘em
Takže například
$ git show HEAD~3
ukáže třetí commit před posledním commitem (tedy čtvrtý).
Protože u řady příkazů se je třeba definovat rozpětí (změny od-do) tak GIT používá tzv. ranges. Základní jsou:
- r1..r2 – je množina commitů z r2 co nejsou v r1
- r1…r2 – je množina commitů co jsou v r1 nebo v r2 ale ne v obou
Předpokládejme, že si pojmenováváte (tagujete) release, pak:
$ git log RELEASE_0.0..RELEASE_0.1
ukáže seznam patchů mezi releases.
Výše uvedené informace jsou dostatečné k pochopení používání GITu a lze je používat v obměnách u většiny GIT příkazů.