Seriál Online kurz Git – Začíname s Gitom – 1. diel

Myslím, že dnes je používanie Gitu alebo iného verziovacieho nástroja štandardom. Mám na mysli používanie nejakého verzionovacieho systému na stredne veľkom projekte. Ja viem, je to trochu sebavedomé vyhlásenie, ale ja už si to bez toho veľmi neviem predstaviť (alebo presnejšie povedané ani nechcem predstaviť). Verzionovací systém je nástroj, ktorý ma tak veľa vlastností podstatných pre softvérový projekt (o chvíľu sa k ním dostaneme), že štartovať čokoľvek väčšie bez neho je podľa mňa ako sťahovať veci po schodoch, keď hneď vedľa je výťah. Git je jedným z takýchto nástrojov, pričom sa dá povedať, že je jeden z najpoužívanejších. Jeho rozsiahle možnosti, integrácia s rôznymi nástrojmi a voľné Git repozitáre, ktoré sú dostupné na internete, z neho často robia voľbu číslo jedna. Aj preto budem tento a niekoľko ďalších článkov venovať práve jemu.

Čo je Git a prečo je vôbec medzi nami?

Než začneme plniť príkazový riadok pokynmi pre Git a hrabať sa vo všelijakých zaujímavých detailoch, je dobré si najprv povedať, o čom to celé je. Pre ľudí, ktorí doteraz o Gite nepočuli alebo maximálne poznajú len to meno, je dobré ak začneme definíciou. Takže, čo je to Git?

Git je optimistický distribuovaný verzionovací systém. Definícia sama o sebe nie je veľmi užitočná, ak nie je jasné, čo znamenajú výrazy v nej a tak si ich teraz pekne kúsok po kúsku rozpytváme.

 

Verzionovací systém

Verzionovací systém je softvér, ktorý ti umožňuje uchovávať rôzne verzie súborov alebo celých adresárových štruktúr. Takýchto softvérov je naozaj veľa (pozri wikipedia) s rôznymi vlastnosťami, ale vo väčšine prípadov sa dá povedať, že umožňujú prehliadať históriu súborov, prípadne získavať presný obraz celej sledovanej adresárovej štruktúry v nejakom momente v histórii.

Distribuovaný systém

Git navrhol a vytvoril Linus Tovards pre verzionovanie zdrojových kódov linuxového jadra (jeho prvý commit zdrojových kódov samotného Gitu, alias Initial revision of „git“, the information manager from hell môžeš nájsť tu). Linuxové jadro je softvér, o ktorom sa dá je jednoznačne prehlásiť, že má distribuovaný tím, keďže do neho prispievajú ľudia z celého sveta. Aj tomuto sa musel Git čo najviac prispôsobiť, a preto bol postavený na princípe distribuovanosti. Aby ale bolo jasné, o čom sa tu vlastne bavíme, musíme sa pozrieť aj na prípady, kedy verzionovancí systém distribuovaný nie je. Takže tu máme 3 typy verzionovacích systémov (z pohľadu rozloženia v sieti):

  1. lokálny – repozitár je dostupný len lokálne na jednom počítači. Slúži teda väčšinou jednej osobe, ktorá si pomocou neho spravuje verzie súborov.
    Kurz Git lokálny verzionovací systém
  2. vzdialený – repozitár je umiestnený niekde v sieti, pričom používatelia sa k nemu pripájajú zo svojich počítačov. Kompletné informácie repozitára sú uložené na serveri a používatelia majú niečo, čo sa zvykne označovať ako working copy. To je verzia súborov v nejakom momente v čase (najčasťejšie ich najaktuálnejšia verzia). Ak chcú uložiť novú verziu, ak si chcú pozrieť starú alebo urobiť čokoľvek, na čo už working copy nestačí, musia sa cez sieť pripojiť k vzdialenému repozitáru. V prípade, že je repozitár niekde nablízku (napr. v rovnakej LAN sieti), nie je to problém. Pamätám si ale projekt, kde bol repozitár skutočne vzdialený (aby som bol presnejší, tak na opačnej strane zemegule) a práca s ním bola neuveriteľne pomalá. Keďže je to nástroj každodennej potreby vývojárov, spomaľovalo to úplne všetko. A práve pre takéto prípady je najvhodnejší distribuovaný typ.
    Git vzdialený verzionovací systém
  3. distribuovaný – ak je problém komunikácia medzi používateľom a repozitárom, ostáva už len jediné. Dostať repozitár naspäť k programátorovi. Ale ak chcete zároveň zachovať, že je repozitár dostupný cez sieť, dostanete niečo takéto:
    Git distribuovaný verzionovací systém
    Hlavná myšlienka je v tom, že každý z používateľov má okrem working copy (teda verziu súborov, s ktorou práve pracuje) aj lokálne všetko ostatné – teda kópiu celého repozitára. Túto kópiu si potom synchronizuje s kópiou na serveri, ktorá je zdieľaná (teda na server v rámci synchronizácie posiela svoje zmeny a tiež takto získava zmeny od ostatných). Práca s repozitárom sa (v ideálnom prípade) zúži len na danú synchronizáciu (pre fanúšikov automatizácie platí, že sa táto synchronizácia dá automatizovať). Chceš si pozrieť históriu súboru? Nie je problém, je to dostupné lokálne. Chceš zistiť, kto a kedy zmenil naposledy daný riadok? Aj to je lokálne. Chceš si zobrať kompletnú verziu súborov z nejakého bodu v čase? Áno, aj to sa dá veľmi rýchlo.

Optimistický systém

Git je zarytý optimista. To v praxi znamená, že optimisticky dovolí dvom alebo viacerým ľuďom naraz meniť ten istý súbor s tým, že nejako sa to pokúsi dať potom dokopy. Naproti tomu existujú pesimistické verzionovacie systémy, ktoré fungujú tak, že najprv je nutné zamknúť súbor aby ho nemohol meniť nikto iný a potom ho začať upravovať. Takto vlastne nemôže dôjsť k tomu, že budú existovať dve paralelné kópie toho istého súboru, ale zároveň to vie pomerne dosť blokovať prácu. Keď som začínal ako programátor, tak prvý projekt, ktorého som sa zúčastnil, bol postavený na Microsoft Visual SourceSafe, čo je práve takýto pesimistický systém. Ešte teraz si spomínam (aj keď je to už poriadne veľa rokov dozadu) ako sa open space-om ozývali volania: „Hej, môžeš mi odomknúť ten a ten súbor. Potrebujem tam zmeniť jeden riadok.“ alebo „Ako dlho na tom ešte budeš pracovať? Zamkol si mi polovicu súborov.“ Tiež si spomínam na ten pocit uvoľnenia, keď sme potom prešli na optimistický verzionovací systém (aj keď Git to nebol), kedy zrazu mohol každý robiť, čo chcel (hoci so zovretým žalúdkom a myšlienkou, ako sa to dá celé dokopy). Každopádne Git je optimistický systém, ktorý teda umožňuje naraz v čase meniť rôznymi ľuďmi ten istý súbor. Spájanie týchto zmien – tzv. mergovanie – potom vo väčšine prípadov prebehne automaticky. V tých zvyšných prípadoch vzniká tzv. konflikt, ktorý je potrebné vyriešiť ručne. Ale to už predbiehame.

Odbočka k histórii Gitu, ktorú sme urobili pri vysvetľovaní distribuovanosti, je veľmi dôležitá. Ak pochopíš, prečo Git vznikol a aký účel mal plniť, tak ľahko pochopíš jeho princíp fungovania. Bol teda vytvorený, aby umožnil veľkému množstvu ľudí fyzicky umiestnených po celom svete paralelne meniť zdrojové kódy linuxového jadra. To ale nie je kompletný zoznam jeho vlastností. Aby bol použiteľný, musel toho vedieť omnoho viac.

Aký je ešte Git?

Okrem vlastností, ktoré som uviedol v základnej definícii sa dá o Gite ešte povedať, že:

  1. pracuje jednoznačne – pri vysvetľovaní tohto pojmu je najlepšie pomôcť si skratkou ACID. Tá v sebe zahŕňa Atomicity, Consistency, Isolation a Durability. V praxi to znamená, že všetky zmeny súborov, ktoré sú spravované Gitom, sú atomické – teda realizované celé alebo vôbec – ďalej konzistentné – teda ich výsledkom je repozitár v normálnom, ďalej použiteľnom stave – potom izolované – hranice medzi jednotlivými zmenami sú dostatočne jasné – a nakoniec trvácne – zmeny by nemali časom (ani nijak inak) zmiznúť.
  2. je adresný – dôležitým aspektom histórie súborov v Gite je, že je jasné kto, kedy a čo zmenil. Každá zmena teda má svojho autora, svoj dátum a čas. Ak si dáte záležať, Git vám bude uchovávať tých informácií aj viac – ku každej zmene, ktorá sa odovzdáva do repozitára je možné doplniť text – tzv. commit message. Tam je dobré uvádzať informácie, ktoré sa zo samotnej zmeny nedajú len tak ľahko vyčítať. K tomu sa ale dostaneme neskôr.
    Git log
  3. nemennosť – trvácnosť musí byť vlastnosťou nielen jednej zmeny, ale repozitára ako celku. Pri Gite sa viete spoľahnúť, že história sa sama nezmaže alebo nezmení. Aj niekoľkoročná história, ktorá obsahuje tisícky zmien, bude vyzerať stále rovnako. Aby som bol úplný, tak aj z toho existujú výnimky a Git má nástroje ako meniť históriu, ale nie je to každodenná činnosť a je možné, že ju v projekte vôbec nebudete realizovať.

Prečo Git používať?

Prečo vlastne používať Git, prípadne iný verzionovací systém? Vo všeobecnosti sa dá povedať, že to nesmierne uľahčuje spoluprácu. Zažil som aj projekty, kde sa zdrojové kódy vymieňali na USB kľúči (alebo v lepšom prípade niekde v zip-e na FTP serveri). V najhoršom prípade tak kolovalo medzi vývojármi niekoľko verzií zdrojových kódov, ktoré potom jedna osoba – integrátor – dával dokopy. To bol človek, o ktorom sa dalo povedať, že svoju prácu nemal príliš rád. Z môjho pohľadu sú verzionovacie systémy momentálne to najlepšie, čo existuje na prácu so zdrojovými kódmi. Dokážu uchovávať spätne rôzne verzie súborov. Okrem samotných zmien ukladajú aj množstvo užitočných informácií o danej zmene (autor, okamih zmeny, atď.). Dovoľujú paralelnú prácu viacerých ľudí nad jedným súborom a potom sa pokúsia (a často sa im to aj darí) dať tieto zmeny samé dokopy. Všetky data a informácie umožňujú efektívne zdieľať po sieti. A v neposlednej rade umožňujú pracovať naraz s niekoľkými vetvami zdrojových kódov, ktoré môžu reprezentovať niečo ako paralelné verzie jedného programu (tzv. branch-e).

Inštalácia Gitu

Teóriu máme za sebou (verím, že si ešte stále tu), môžeme sa pustiť do praxe. Inštalácia Gitu je pomerne jednoduchá, preto ju nebudem popisovať krok po kroku. Aktuálnu verziu si je možné stiahnuť zo stránky http://www.git-scm.com/downloads, alebo nainštalovať z repozitára balíkov. Tu je nutné povedať, že inštaláciou Gitu získaš kompletný softvér, ktorý je schopný prevádzkovať na tvojom počítači repozitár a zároveň klientský command line nástroj, ktorý ti umožní s tým repozitárom pracovať. Okrem command lina klienta má Git obrovské množstvo iných  klientov, ktoré sú buď samostatné (napr. Tortoise Git) alebo integrované do IDE (plugin pre Eclipse, NetBeans, VisualStudio atď.). Ak bola inštalácia úspešná, tak vieš prítomnosť Gitu otestovať cez príkaz:

> git –version

git version 2.32.0.windows.1

Git Inštalácia SDK Bash Login

Vytvárame Git repozitár

Bez repozitára sa ďalej nepohneme, takže je to prvé, čo musíme spraviť. Takže v priečinku, do ktorého budeme dávať verzionované súbory (alebo tam, kde už tie súbory sú), spustíme príkaz:

> git init

Initialized empty Git repository in …/.git/

Ak sa do toho priečinku pozriete, tak zistíte, že na prvý pohľad sa nič nezmenilo. Nič nenasvedčuje tomu, že ste si práve vyrobili magický priečinok, ktorý vám umožňuje sledovať spätne rôzne verzie, a tak sa de facto presúvať hore dole v čase. Tajomstvo je ukryté v špeciálnom (skrytom) .git priečinku, ktorý bol vytvorený. Tento .git priečinok je v podstate celý repozitár, a to čo je mimo neho, je vaša working copy, v ktorej od tohto momentu sú všetky zmeny sledované. Niekedy v ďalších dieloch seriálu sa pozrieme trochu aj do vnútra tohto zvláštneho priečinka. Zatiaľ ti o tom stačí vedieť, že ho treba nechať tak a nebabrať do neho. Všetko, čo sa nachádza v ňom, je spravované samotným Gitom a neodborný zásah sa môže skončiť katastrofou. Treba ešte poznamenať, že na rozdiel od niektorých iných verzionovacích systémov, Git má svoje informácie uložené len v tomto jednom, hlavnom (root) priečinku a už nič iné neukladá niekde nižšie v adresárovej štruktúre working copy.

Vytváranie repozitára má ešte jeden špeciálny prípad a to pomocou prepínača bare:

> git init –bare

Initialized empty Git repository in …

Git init vytváranie repozitárov

Tento prepínač sa používa, ak chcete vytvoriť serverový repozitár. Teda repozitár na serveri, ktorý bude slúžiť výlučne na to, aby sa na neho pripájali iné počítače v sieti a voči nemu synchronizovali obsah svojich kópií repozitárov. Nepotrebuje preto working copy, pretože lokálne na ňom nikto pracovať nebude, a teda ju ani nemá. Obsah, ktorý je inak uložený v .git priečinku je skopírovaný priamo v adresári, kde ste repozitár vytvorili.

Prvá zmena

Ak máme vytvorený repozitár, môžeme sa pustiť do práce. Pridáme si teda do repozitára súbor a jeho pridanie uložíme ako zmenu. Takže prvý krok je vytvoriť súbor index.html, ktorý bude obsahovať len text „Hello world“ a ktorý uložíte priamo do vašej working copy. Následne necháme Git skontrolovať vašu working copy a to pomocou príkazu:

> git status

On branch master

Initial commit

Untracked files:

(use „git add <file>…“ to include in what will be committed)

index.html

nothing added to commit but untracked files present (use „git add“ to track)

Čo sa nám snaží Git povedať? Tak v prvom rade, že naša working copy je nastavená na branch master. Než sa dostaneme ku konceptu branchov, teraz si povieme len, že v reči Gitu je master vetva zdrojových kódov, ktorá predstavuje hlavnú vetvu a ktorá by mala byť najviac menená (ak to vyzerá nejasne alebo komplikovane, tak treba vydržať, k branchom a mastrovi sa určite vrátime neskôr).

Ďalej nám hlásením Initial commit hovorí, že zatiaľ v repozitári nebol vytvorený žiaden commit. Čo to commit je? Commit predstavuje nejakú ucelenú zmenu v repozitári. Môže obsahovať viacero zmien v súboroch, ich pridanie alebo odobratie. Tie zmeny by ale mali spolu nejako súvisieť. Najlepšie commit vystihuje pridanie nejakej funkcionality alebo opravu chyby. Commit má svojho autora, dátum a čas vzniku a tiež svoju commit message. A v Gite má tiež svoj jedinečný SHA1 hash, ale k tomu neskôr. Treba ešte dodať, že commit je najmenšia jednotka v histórii Gitu, s ktorou sa dá pracovať. Preto by zmeny súborov v jednom commite mali reprezentovať nejakú ucelenú zmenu v zdrojových kódoch a to podľa možnosti čo najmenšiu. Časom sa dostaneme k technikám ako s commitmi v histórii pracovať a nič nie je horšie, ako keď zistíte, že commit obsahuje viacero nesúvisiacich zmien, pričom vy potrebujete nejako pracovať len s jednou z nich.

V našom výpise statusu sa ešte nachádza zoznam nesledovaných – untracked – súborov. Medzi nimi je prekvapivo ten náš. Čo to znamená nesledovaný súbor? Akýkoľvek súbor, ktorý sa objaví vo working copy Git vidí, ale jeho históriu začne sledovať, až keď mu to poviete. To sa robí pomocou príkazu git add. Takže poďme na to:

> git add index.html

Následne si opäť skontrolujeme, ako to vidí git:

> git status

On branch master

Initial commit

Changes to be committed:

(use „git rm –cached <file>…“ to unstage)

new file:   index.html

index.html je teraz už nový súbor. To znamená, že jeho pridanie môže byť súčasťou commitu. Všetky zmeny, ktoré chceme, aby Git vykonal, sa musia zaradiť do tzv. staged changes. To si môžeš predstaviť ako nejaký zoznam zmien, ktoré sa udiali vo working copy a ktoré chcem, aby sa zaradili  do najbližšieho commitu. Môžu totiž nastať prípady, kedy niektoré zmeny z working copy nechceš commitnuť (po commite sa ich chceš napríklad zbaviť) alebo chceš zmeny rozdeliť do viacerých – samostatných – commitov. Staged changes teda predstavujú určitý medzistupeň medzi zmenou vo working copy a jej zaradením do commitu.

Git working copy commit

Ak máme súbor pridaný, neostáva nič iné, len ho commitnuť. Poďme na to:

> git commit -m „Zaciatok prac na stranke“

[master (root-commit) e4c0627] Zaciatok prace na stranke

1 file changed, 1 insertion(+)

create mode 100644 index.html

Výsledok tohto príkazu je náš prvý commit. To za príznakom „-m“ je commit message, ktorá by ho mala čo najlepšie popisovať. Vedieť písať správne a zmysluplné commit message je zručnosť sama o sebe (a tiež to vyžaduje disciplínu). Aj k tomuto sa vrátime neskôr. Git nám vrátil stručný popis toho, čo sa stalo a to že bol v branch master vytvorený commit, ktorého SHA1 začína na e4c0627. Ten hash týmto naozaj len začína, lebo v skutočnosti nemá 7 znakov ale 40. Git umožňuje pracovať aj so skrátenými verziami hashov tak dlho, ako sú unikátne v rámci repozitára. Okrem toho výpis obsahuje zoznam toho, čo sa commitlo (pridal sa jeden súbor) a na záver informáciu o tom, ako sú na novom súbore nastavené práva a čo je to za typ súboru.

Ak si znova skontrolujeme obsah working copy, toto bude výsledok:

> git status

On branch master

nothing to commit, working directory clean

Stále pracujeme s branch master (bolo by divné, keby nie) a momentálne nemáme žiadne zmeny vo working copy, ani nič v staged changes. Commit bol teda úspešný, je čas si dať kávu.

Záver a sumarizácia

Git je optimistický distribuovaný verzionovací systém, ktorý s tebou bude vždy rád spolupracovať a niekedy ti môže zachrániť krk. Je to nástroj na cestovanie v čase a archeologický výskum („ … kedy a kto zmenil tento riadok?“). Je to nástroj mocný, ale aj preto nie úplne jednoduchý. Dnes sme prišli toto svoje nové fáro pozrieť a naštartovať. V ďalšom diely sa už trochu povozíme, aby sme videli, čo to dokáže. A verte mi, bude to zaujímavé.

Tip: Mrknite na náš online kurz Git.

Prehľad publikovaných článkov

  1. Seriál Online kurz Git – Začíname s Gitom – 1. diel
  2. Seriál Online kurz Git – Lokálna Práca so Súbormi – 2. diel
  3. Seriál Online kurz Git – V Hlbinách Súborového Systému – 3. diel
  4. Seriál Online kurz Git – Paralelné svety a Git branch – 4. diel
  5. Seriál Online kurz Git – Mergovanie s Konfliktom, Tagy a Skrytie Zmien – 5. diel
  6. Seriál Online kurz Git – Vzdialené repozitáre, GitHub, Bitbucket – 6. diel
  7. Seriál Online kurz Git – Clean, Reset, Rebase, Revert nástroje do každého počasia – 7. diel
  8. Seriál Online kurz Git – Najčastejšie problémy, faily a fuckupy – 8. diel

Autor

Miroslav Reiter

Programátor, manažér a marketér, ktorý mudruje vo vlastnej vzdelávacej spoločnosti IT Academy. Workoholik so 134 certifikáciami a 13 titulmi. Vytvoril som vzdelávaciu platformu vita.sk, pretože milujem vzdelávanie a všetko čo k nemu patrí. Pomáham firmám ale aj jednotlivcom zlepšovať ich podnikanie a IT. Certifikácie: Microsoft certifikovaný tréner, Google certifikovaný tréner, ITIL, PRINCE2 tréner. 40000+ vyškolených klientov a 1000+ firiem, ktorým som pomohol Referencie: Národná Rada SR, Slovnaft, IBM, Panasonic, Ministerstvo obrany SR, ČSOB, Generali, Tatra banka, Európska komisia, SPP, Pixel Federation, ESET.