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. Git je jeden z najpopulárnejších systémov na správu verzií, ktorý sa používa na sledovanie zmien v kóde a spoluprácu medzi vývojármi. Tento článok je prvým dielom série, ktorá vás prevedie základmi práce s Gitom. Dnes sa pozrieme na to, čo je Git, prečo je dôležitý a ako začať používať jeho základné príkazy.
Č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.
Git je distribuovaný verzionovací systém, ktorý umožňuje viacerým vývojárom pracovať na rovnakom projekte súčasne. Každý vývojár má plnú kópiu celého projektu, vrátane celej histórie zmien. Toto umožňuje jednoduché experimentovanie a spoluprácu bez strachu zo straty dát.
Hlavné výhody Git:
- Distribuovaná architektúra: Každý má plnú kópiu projektu, takže žiadne centralizované úložisko nie je nevyhnutné.
- Rýchlosť: Väčšina operácií je veľmi rýchla, pretože sú lokálne.
- Bezpečnosť: Zmeny sú identifikované pomocou SHA-1 hashov, čo zaisťuje integritu dát.
- Flexibilita: Git podporuje rôzne pracovné štýly a workflowy.
Inštalácia Git
Predtým, než začneme používať Git, musíme ho nainštalovať. Môžete si ho stiahnuť a nainštalovať z oficiálnej stránky. Inštalácia je dostupná pre rôzne operačné systémy, vrátane Microsoft Windows, macOS a Linux.
Po inštalácii si nastavte svoje meno a e-mail, ktoré budú používané pri commitovaní zmien.
git config –global user.name „Vaše Meno“
git config –global user.email „vas.email@example.com“
Vytvorenie nového repozitára
Nový Git repozitár môžete vytvoriť pomocou príkazu git init
. Tento príkaz inicializuje nový repozitár v aktuálnom adresári.
Príklad:
mkdir moj-projekt
cd moj-projekt
git init
Klonovanie existujúceho repozitára
Ak chcete pracovať na existujúcom projekte, môžete ho klonovať pomocou príkazu git clone
. Tento príkaz stiahne môj celý repozitár vrátane celej histórie zmien.
Príklad:
git clone https://github.com/miroslav-reiter/Kurzy_SAV_DataScience_BI.git
Pridávanie súborov do repozitára
Keď vytvoríte alebo upravíte súbory, musíte ich pridať do staging area predtým, než ich commitnete. Na pridanie súborov do staging area použite príkaz git add
.
Príklad:
echo „print(‚Hello, world!‘)“ > hello.py # Vytvorenie nového súboru
git add hello.py # Pridanie súboru do staging area
Commitovanie zmien
Commitovanie je proces, ktorým ukladáte zmeny v repozitári. Každý commit má unikátny identifikátor a obsahuje správu, ktorá opisuje vykonané zmeny.
Príklad:
git commit -m „Pridanie hello.py s jednoduchým programom“ # Commitovanie zmien
Zobrazenie stavu repozitára
Príkaz git status
vám umožní zobraziť aktuálny stav pracovného adresára a staging area. Ukazuje, ktoré súbory boli zmenené, pridané alebo odstránené.
Príklad:
git status # Zobrazenie stavu repozitára
Zobrazenie histórie commitov
Príkaz git log
zobrazuje históriu commitov v repozitári. Ukazuje informácie o každom commite, vrátane autora, dátumu a správy.
Príklad:
git log # Zobrazenie histórie commitov
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):
- 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.
- 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.
- 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:
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:
- 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úť.
- 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.
- 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
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 …
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 (Git Change)
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.
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
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ý. Tento úvodný diel vás previedol základmi, ako sú inštalácia Git, vytváranie nových repozitárov, pridávanie a commitovanie súborov. V nasledujúcich dieloch sa pozrieme na pokročilejšie techniky a príkazy, ktoré vám pomôžu ešte viac využiť potenciál Git. 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é.
Odporúčania na prácu s Gitom
Pri práci s Gitom dbajte na pravidelné commitovanie zmien, používanie vetiev na izolovanie rôznych častí projektu a sledovanie stavu projektu pomocou git status
. Tieto postupy vám pomôžu udržiavať váš projekt organizovaný a efektívny.
Objavte online kurzy na Git a GitHub
Prehľad publikovaných článkov
- Seriál Online kurz Git – Začíname s Gitom – 1. diel
- Seriál Online kurz Git – Lokálna Práca so Súbormi – 2. diel
- Seriál Online kurz Git – V Hlbinách Súborového Systému – 3. diel
- Seriál Online kurz Git – Paralelné svety a Git branch – 4. diel
- Seriál Online kurz Git – Mergovanie s Konfliktom, Tagy a Skrytie Zmien – 5. diel
- Seriál Online kurz Git – Vzdialené repozitáre, GitHub, Bitbucket – 6. diel
- Seriál Online kurz Git – Clean, Reset, Rebase, Revert nástroje do každého počasia – 7. diel
- Seriál Online kurz Git – Najčastejšie problémy, faily a fuckupy – 8. diel