Príručka Visual Git

Iné jazyky:

Táto stránka predstavuje stručnú vizuálnu príručku najpoužívanejších príkazov programu Git. Je určená k prehĺbeniu vášho pochopenia toho, ako Git funguje. Ak vás zaujíma to, ako bola táto stránka vytvorená, je vám k dispozícii môj repozitár na GitHub-e.

Poznámka k slovenskému prekladu: V texte je použitý výraz revízia na označenie konkrétnej verzie súborov uložených v histórii projektového archívu. Výraz komit potom označuje aktivitu vloženia novej revízie do histórie projektového archívu.

Obsah

  1. Základné použitie
  2. Použité konvencie
  3. Podrobne o príkazoch
    1. Rozdielová analýza (diff)
    2. Komitovanie (commit)
    3. Kopírovanie z archívu do pracovného adresára (checkout)
    4. Komitovanie s odpojenou hlavou (detached HEAD)
    5. Resetovanie (reset)
    6. Spájanie zmien (merge)
    7. Zbieranie čerešničiek (cherry-pick)
    8. Spájanie vetiev (rebase)
  4. Technické poznámky

Základné použitie

Vyššie uvedené štyri príkazy umožňujú kopírovanie súborov medzi pracovným adresárom (working directory), predsieňou (index, stage) a projektovým archívom (history).

Prepínač príkazového riadku -p v príkazoch git reset -p, git checkout -p alebo git add -p namiesto definovania konkrétnych súborov (prípadne spolu s tým) umožní používateľovi interaktívny výber častí zmien, ktoré sa skopírujú.

Je tiež možné preskočiť predsieň a skopírovať súbory do pracovného adresára priamo z archívu alebo komitovať súbory bez predošlého vloženia do predsiene.

Použité konvencie

V ďalších vysvetleniach budú použité grafy s nasledujúcim formátom.

Revízie sú zobrazené zelenou farbou ako 5-ciferné identifikátory, pričom odkazujú na svojich rodičov. Vetvy sú zobrazené oranžovou farbou, pričom odkazujú na konkrétne revízie. Aktuálna vetva je identifikovaná špeciálnym odkazom HEAD (hlava), ktorý je "pripojený" k tejto vetve. Na tomto obrázku je vyobrazených posledných päť revízií, kde najnovšou je revízia identifikovaná ako ed489. main (aktuálna vetva) odkazuje na túto revíziu, zatiaľ čo stable (iná vetva) odkazuje na jedného z predkov revízie vo vetve main.

Podrobne o príkazoch

Rozdielová analýza (diff)

Existujú rozličné spôsoby ako nazerať na rozdiely medzi revíziami. Nižšie uvádzame niektoré typické príklady. Rozsah porovnávania pri ktoromkoľvek z týchto príkazov je možné prostredníctvom dodatočného parametra súbory obmedziť na tieto uvedené súbory.

Komit (commit)

Keď komitujete, Git vytvorí nový objekt komitu (t.j. novú revíziu) použijúc súbory z predsiene, ktorému nastaví odkaz na rodiča na aktuálnu revíziu. Následne presmeruje odkaz aktuálnej vetvy na túto novú revíziu. Na obrázku nižšie je aktuálnou vetvou vetva main. Pred spustením príkazu odkazovala vetva main na ed489. Následne bola vytvorená nová revízia f0cec s rodičom ed489. Napokon sa odkaz vetvy main presunul na túto novú revíziu.

Rovnaký priebeh má dokonca i prípad, kedy aktuálna vetva je predkom inej. Nižšie je zobrazený komit na vetve stable, ktorá bola predkom vetvy main. Výsledkom je vznik revízie 1800b. Dôsledkom tohto komitu už vetva stable nie je viac predkom vetvy main. Na neskoršie spojenie zmien z takto vzniknutých dvoch línií histórie bude potrebné použiť príkaz merge (alebo rebase).

Niekedy sa pritrafí, že komit obsahuje chybu, čo sa však dá ľahko napraviť pomocou príkazu git commit --amend. Pri použití tohto príkazu, Git vytvorí novú revíziu s rovnakým rodičom ako má tá aktuálna. (Pôvodná aktuálna revízia bude zahodená, ak sa na ňu už nič viac neodkazuje.)

Štvrtým prípadom je komitovanie s odpojenou hlavou, čo objasníme neskôr.

Kopírovanie z archívu do pracovného adresára (checkout)

Príkaz git checkout sa používa na kopírovanie súborov z archívu (alebo z predsiene) do pracovného adresára a na prípadnú zmenu vetiev.

Keď sa uvedie názov súboru (a/alebo prepínač -p), Git skopíruje definované súbory z danej revízie do predsiene a pracovného adresára. Napríklad príkaz git checkout HEAD~ foo.c skopíruje súbor foo.c z revízie nazvanej HEAD~ (rodič aktuálnej revízie) do pracovného adresára a tiež do predsiene. (Ak sa neuvedie názov žiadnej revízie, súbory sa skopírujú z predsiene.) Všimnite si, že aktuálna vetva ostáva nezmenená.

Keď sa názov súboru neuvedie, ale odkazom je (lokálna) vetva, hlava (špeciálny odkaz HEAD) sa presunie do tejto vetvy (t.j. "prepneme sa" do tejto vetvy) a potom sa obsah predsiene i pracovného adresára upraví podľa obsahu aktuálnej revízie v tejto vetve. Všetky súbory, ktoré existujú v novšej revízii (a47c3 na obrázku nižšie), budú skopírované; akýkoľvek súbor, ktorý existuje v staršej revízii (ed489), avšak nie v novšej revízii, bude zmazaný; a akýkoľvek súbor, ktorý nie je súčasťou ani jednej z revízií, bude ignorovaný.

Keď sa názov súboru neuvedie a odkazom nie je (lokálna) vetva — povedzme, je to tag, vzdialená vetva, SHA-1 identifikátor revízie alebo referenčný výraz napr. ako main~3 — dostaneme anonymnú vetvu nazývanú odpojená hlava (detached HEAD). Toto je užitočné pri prechádzaní cez históriu v archíve. Povedzme, že chcete skompilovať Git, verziu 1.6.6.1. Môžete spustiť príkaz git checkout v1.6.6.1 (v tomto prípade ide o tag, nie o vetvu), skompilovať, nainštalovať a napokon sa prepnúť späť do inej vetvy, napríklad git checkout main. Komitovanie s odpojenou hlavou však funguje trochu odlišne; toto pokrýva odstavec nižšie.

Komitovanie s odpojenou hlavou (detached HEAD)

Pri odpojení hlavy (HEAD), komitovanie funguje ako obvykle s tým rozdielom, že žiadna pomenovaná vetva sa nezaktualizuje. (Môžete na to nazerať ako na anonymnú vetvu.)

Akonáhle skopírujete niektorú inú revíziu z archívu (prostredníctvom príkazu git checkout), napríklad z vetvy main, (je predpoklad, že) na pôvodnú revíziu už nič iné neodkazuje a táto sa teda stratí. Všimnite si, že po vykonaní príkazu už nič viac neodkazuje na revíziu 2eecb.

Na druhej strane, ak chcete uložiť tento stav, môžete vytvoriť novú pomenovanú vetvu pomocou príkazu git checkout -b názov-vetvy.

Resetovanie (reset)

Resetovací príkaz git reset presúva aktuálnu vetvu na inú pozíciu a prípadne aktualizuje predsieň a pracovný adresár. Používa sa tiež na kopírovanie súborov z archívu (z existujúcej revízie) do predsiene bezo zmeny obsahu pracovného adresára.

Ak sa uvedie len revízia bez názvov súborov, presunie sa aktuálna vetva na túto revíziu a následne sa na túto revíziu zaktualizuje aj obsah predsiene. Prepínač --hard spôsobí aktualizáciu aj pracovného adresára. Prepínač --soft zachová predsieň i pracovný adresár bezo zmien.

Neuvedenie revízie sa rovná použitiu špeciálneho odkazu hlava (HEAD). V tomto prípade sa vetva nepresúva, len obsah predsiene (príp. s použitím prepínača --hard aj pracovného adresára) sa skopíruje z poslednej revízie.

Ak sa uvedie názov súboru (a/alebo prepínač -p), potom príkaz pracuje podobne ako príkaz checkout s názvom súboru s tým, že sa zaktualizuje iba predsieň (pracovný adresár nie). (Je tiež možné uviesť revíziu, z ktorej sa má zobrať obsah súborov, inú než hlava (HEAD).)

Spájanie zmien (merge)

Príkaz vytvára novú revíziu, ktorá zahŕňa zmeny z iných revízií. Pred vykonaním príkazu musí obsah predsiene zodpovedať aktuálnej revízii. Triviálnym prípadom je ak spájaná revízia je predkom aktuálnej revízie - v tomto prípade sa neudeje nič. Ďalším najjednoduchším prípadom je ak aktuálna revízia je predkom spájanej revízie. Toto má za následok spojenie zmien pretočením dopredu (tzv. fast-forward merge), kedy je odkaz vetvy jednoducho presunutý s následným skopírovaním obsahu nového odkazu (t.j. spájanej revízie) do predsiene.

V iných prípadoch musí nastať "skutočné" spájanie. Môžete si zvoliť iné stratégie, avšak obvykle sa vykonáva "rekurzívne" spájanie, kedy sa v princípe vezme aktuálna revízia (ed489 na obrázku nižšie), spájaná revízia (33104) a ich najnovší spoločný predok (b325c) a vykoná sa trojcestné spájanie. Výsledok sa uloží do pracovného adresára i do predsiene. Následne nastane komit, pri ktorom vzniká nová revízia s pridaným dodatočným rodičom (33104).

Zbieranie čerešničiek (cherry-pick)

Príkaz git cherry-pick "zreplikuje" komit z inej vetvy do aktuálnej vetvy. V aktuálnej vetve pritom vznikne nová revízia s rovnakým popisom i obsahom ako má referencovaný komit.

Spájanie vetiev (rebase)

Spájanie vetiev je alternatívou k spájaniu zmien pre prípad zlučovania viacerých vetiev. Zatiaľ čo spájanie zmien (merge) vytvorí jednoduchú revíziu s dvomi rodičmi tvoriac nelineárnu históriu v archíve, spájanie vetiev (rebase) zreplikuje všetky komity z aktuálnej vetvy do inej vytvoriac lineárnu históriu v archíve. Vo svojej podstate sa v prípade spájania vetiev jedná o automatizovaný spôsob vykonania viacerých príkazov cherry-pick v rade za sebou.

Vyššie uvedený príkaz vezme všetky také revízie, ktoré existujú vo vetve topic, nie však vo vetve main (menovite 169a6 a 2c33a), zreplikuje ich do vetvy main a následne presunie hlavu vetvy na nový vrchol. Ak na staré revízie po vykonaní príkazu nič viac neodkazuje, budú tieto odstránené pomocou nástroja na odstraňovanie neplatných položiek (garbage collected).

Pre obmedzenie toho ako ďaleko do histórie sa vracať, použite prepínač --onto. Nasledujúci príkaz zreplikuje do vetvy main najnovšie komity z aktuálnej vetvy počnúc revíziou nasledujúcou po revízii 169a6, konkrétne revíziu 2c33a.

Existuje tiež interaktívny režim príkazu git rebase --interactive, ktorý umožňuje robiť zložitejšie veci než len jednoduché zreplikovanie komitov, konkrétne zrušenie, preusporiadanie, úpravu či zlučovanie komitov. Pre toto nie je k dispozícii žiaden zrejmý obrázok; v prípade záujmu o podrobnosti si preštudujte git-rebase(1).

Technické poznámky

Obsah súborov sa neuchováva priamo v predsieni (.git/index) alebo v objektoch komitov. Každý súbor sa nachádza v databáze objektov (.git/objects) vo formáte blob (binary large object), identifikovaný svojim SHA-1 hash-om. Indexový súbor (obsah predsiene) obsahuje zoznam názvov súborov spolu s identifikátorom pridruženého binárneho objektu blob a tiež ďalšie dáta. Pre revízie existuje dodatočný dátový typ strom, ktorý je rovnako identifikovaný svojim hash-om. Stromy zodpovedajú adresárom v pracovnom adresári a obsahujú zoznam stromov a blob-ov prislúchajúcich ku každému názvu súboru v tom adresári. Každá revízia má uložený identifikátor jeho stromu najvyššej úrovne, ktorý následne obsahuje všetky svoje blob-y a ostatné stromy naviazané na túto revíziu.

Ak vytvoríte revíziu pomocou odpojenej hlavy, na túto poslednú revíziu skutočne niečo odkazuje: tzv. reflog hlavy. Po nejakom čase však tento vyprší, takže túto revíziu napokon odstráni nástroj na odstraňovanie neplatných položiek, podobne ako pri revíziách po vykonaní príkazu git commit --amend alebo git rebase.


Copyright © 2010, Mark Lodato. Slovenský preklad © 2013, Ľudovít Lučenič.

Toto dielo je licencované Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States licenciou.

Want to translate into another language?