IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
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í.

5. diel - Git - Skúmanie histórie

V minulom diele sme si niečo povedali o základoch gitu. Dnes si ukážeme, ako môžeme k jednotlivým commitům pristupovať. S tým súvisí prehľadávanie histórie, jedna z vecí, v ktorej Git vyniká.

Pomenovanie COMMIT

V GITU sa na commit môžeme odkazovať niekoľkými spôsobmi. Týmito odkazy potom môžeme jednoznačne identifikovať konkrétne commit. Sú to:

  • 40-znakový hash COMMIT
  • Meno vetvy
  • Meno tagu

Hash COMMIT

Ako sme si povedali v minulom diele, každý commit je definovaný svojím hashom. Jedná sa o 40-tich miestne hexadecimálne číslo, ktoré zistíte buď z GUI alebo príkazom git log alebo git show. Toto číslo je jedinečné pre každý commit. Pre identifikáciu COMMIT však nemusíte toto číslo písať celé, stačí iba jeho niekoľko prvých znakov. Tentoraz si pre demo naklonuje repozitár Linuxu.

$ git log --oneline
fd5984d Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
ad6ede8 Merge tag 'pm+acpi-3.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
10f3291 Merge branch 'akpm' (fixes from Andrew Morton)
b0108f9 kexec: purgatory: add clean-up for purgatory direktory
16b0371 Documentation/kdump/kdump.txt: add ARM description
…… a spoustu dalších, výsledný textový soubor má asi 16MB

Meno vetvy

K vetvám sme sa ešte nedostali, budeme ich preberať v budúcom diele. Každá vetva sa skladá aspoň z jedného COMMIT. Aj keď vytvoríte nový lokálnej repozitár a urobíte prvý commit, vytvoríte tým hlavná vetva "master". Zoznam vetiev zobrazíte príkazom git branch. Ako odkaz môžeme použiť práve meno tejto vetvy, pritom vetva iba odkazuje na posledný commit, ktorý bol v danej vetve vytvorený. Z toho vyplýva, že ak ste nevytvárali nové vetvy, vetva "master" bude ukazovať na poslednú commit, ktorý ste urobili.

$ git branch
* master

V túto chvíľu sa vypíše iba vetva master, pretože pri klonovaní repozitára dochádza ku klonovaniu iba jedinej vetvy. Ide o tú vetvu, ktorú vývojári zverejnili. To však neznamená, že projekt nemôžeme mať viac vetiev, iba ich majú vývojári lokálne pri sebe.

Tagy

Tagy môžeme pridávať ľubovoľne ku ktorémukoľvek COMMIT. Môžeme si nimi označiť dôležité miesta v histórii, nové verzie, opravy dôležitých chýb a čokoľvek iného. Všetky tagy v projekte vypíšeme príkazom git tag. Pritom sú tagy zoradené od najstarších k novším.

$ git tag
v2.6.11
v2.6.11-tree
v2.6.12
v2.6.12-rc2
v2.6.12-rc3
v2.6.12-rc4
… novější tagy

Tagy delíme na dve verzie, ľahké (lightweight) a anotované (Annotated). Ľahký tag sa veľmi podobá vetve, iba s tým rozdielom, že sa neprepravujte. Teda slúži len ako odkaz na určitý commit. Zbierku tag už je však niečo iné, ide o plnohodnotný objekt, porovnateľný s COMMIT. Obsahuje všetky identifikačné informácie ako commit (meno autora, čas, hash). Môžeme k nemu tiež pridať správu.

Pre vytvorenie ľahkého tagu nám stačí iba prejsť na commit, ktorý chceme označiť a zadať príkaz git tag jmenoTagu. Pre vytvorenie anotovaného tagu pridáme možnosť -a, teda príkaz bude podľa vzoru git tag -a jmenoTagu -m "Sprava k tagu". Opäť si ukážeme ukážku.

$ git tag LightTag
$ git tag -a AnnotedTag –m „Vytvoreni annoted tagu“
$ git tag
AnnotedTag
LightTag
v2.6.11
v2.6.11-tree
....

Prechod medzi COMMIT

K prechodu medzi COMMIT slúži príkaz git checkout. Ten vás presunie na miesto, ktoré ste mu zadali ako parameter. Zároveň s tým aktualizuje pracovnou zložku do stavu, ako vyzerala práve v tom určitom COMMIT. Na tomto mieste potom môžeme vytvárať nové vetvy, pridávať tagy alebo aj upravovať commit. Po vykonaní práce sa dostaneme naspäť príkazom git checkout master. Tým prepneme na vrchol vetvy master (teda na jej posledný commit). Je však tiež možné presúvať sa na tagy, poprípade v rámci vetiev. Ako sa teda dostanem na tag v3.9?

$ git checkout v3.9
Checking out files: 100% (32848/32848), done.
Note: checking out 'v3.9'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at c1be5a5... Linux 3.9

Čo nám výstup hovorí? V prvom odseku nás informuje o tom, že sme prešli do "detached HEAD" stave. Pre nás to znamená, že môžeme robiť čokoľvek, bez toho aby sme ovplyvnili akékoľvek iné vetvy. Zároveň ale musíme počítať s tým, že akonáhle prejdeme na iné miesto, všetky zmeny sa zrušia. V druhom odseku nám Git hovorí, ako tento problém môžeme vyriešiť. Zavolaním git checkout s parametrom -b. Tým sa vlastne vytvorí nová vetva. O tom ale bude až ďalší článok. Nakoniec nám napíše, že sme aktuálne na COMMIT s hashom c1be5a5 ... a vypíše nám jeho popis. Zároveň si všimnite, že sa aktualizoval pracovný adresár. Môžete pracovať so súbormi rovnako ako v čase, keď bol tento commit vytvorený. Pre prejdení späť zadáme git checkout master.

Git log a show

S príkazy git log a git show sme sa už stretli. Git log zobrazí históriu commit, zatiaľ čo git show posledný commit. To ale nie je všetky ich funkčnosť. Git log dokáže zobraziť históriu od určitého commit, medzi dvoma COMMIT pod.

git log v3.9..                  # commity od tagu v3.9
git log v3.8..v3.9              # commity mezi tagy v3.8 a v3.9
git log --since=“1 year ago“    # commity rok zpátky
git log firmware/ihex2fw.c      # commity které upravili soubor firmware/ihex2fw.c

Uvedené spôsoby ide samozrejme tiež kombinovať. K tomu by som ešte rád spomenul atribút --oneline, ktorý každý commit zobrazí iba na jednom riadku. Pritom zobrazí len začiatok hashe COMMIT a ich popis.

$ git log --oneline firmware/ihex2fw.c
b8cb464 ihex: fix unused return value compiler warning
2473238 ihex: add support for CS:IP/EIP records
b7ed698 Documentation/: fix warnings from -Wmissing-prototypes in HOSTCFLAGS
556b0f5 Revert "fix modules_install via NFS"
8b249b6 fix modules_install via NFS
85ebd00 Fix IHEX firmware generation/loading
59890f7 ihex: Add support for long records to ihex2fw.c
8bd6b22 ihex: add ihex2fw tool for converting HEX files into firmware images
$ git log --since=“5 years ago“  --oneline firmware/ihex2fw.c
b8cb464 ihex: fix unused return value compiler warning
2473238 ihex: add support for CS:IP/EIP records
b7ed698 Documentation/: fix warnings from -Wmissing-prototypes in HOSTCFLAGS

Druhým príkazom je git show. Tomu môžeme odovzdať odkaz ku konkrétnemu COMMIT alebo tagu. Pozrieme sa teda na commit b8cb464, ktorý by mal meniť súbor ihex2fw.c.

$ git show b8cb464
commit b8cb464e4a8abc60ad5a43e0375fec8a3c728167
Author: Chris Ruffin <[email protected]>
Date:   Wed Jan 12 16:59:38 2011 -0800

    ihex: fix unused return value compiler warning

    Fix unusued return value compiler warnings due to unchecked write() calls.

    [[email protected]: correctly handle short writes]
    Signed-off-by: Chris Ruffin <[email protected]>
    Cc: Mark Brown <[email protected]>
    Signed-off-by: Andrew Morton <[email protected]>
    Signed-off-by: Linus Torvalds <[email protected]>

diff --git a/firmware/ihex2fw.c b/firmware/ihex2fw.c
index ba0cf0b..cf38e15 100644
--- a/firmware/ihex2fw.c
+++ b/firmware/ihex2fw.c

Opäť sa nám zobrazí základné informácie o commit, potom výpis pokračuje popisom COMMIT. Potom je hlavička emailu. To je preto, že autori repozitára musí overiť, či sa jedná o funkčné commit. Keby mohol ktokoľvek prispievať, každý by si mohol s projektom robiť čo chce (mohol by napríklad zaniesť bug alebo nejaký vírus). Preto musí autori repozitára overiť, či ide o funkčné commit. A práve táto žiadosť o pridanie vlastného COMMIT do projektu prebieha cez email. Na ďalšom riadku vidíme, že sa zmenil iba súbor ihex2fw. Ďalej vo výpise je vypísané čo sa zmenilo (riadok označený mínus bol zmazaný, zatiaľ čo riadok označený + bol pridaný). Takto môžete prejsť všetky COMMIT a zistiť, čo sa kde zmenilo, kedy sa to zmenilo a kto za zmenou stoja.

Rozdiel

Ak by ste však chceli zobraziť príkaz show medzi dvoma commit, ako sme to napríklad vypisovali u git log, tak zistíte, že vás Git nepustí. Pre tento účel existuje samostatný príkaz git diff. Git diff bez parametrov vypíše rozdiel medzi pracovnou zložkou a Stage (indexom). Príkaz git diff HEAD vypíše rozdiel medzi posledným COMMIT a pracovné zložkou. Okrem toho môžeme ako parameter odovzdať rovnaký reťazec, ako u logu.

Ak chceme meniť pracovné zložku, slúži k tomu tiež niekoľko príkazov. Ak ste editovali súbor a chcete vrátiť jeho zmeny, tak ako boli u posledného commit, slúži na to príkaz git reset HEAD <file> alebo git checkout HEAD <file> (záleží na situácii, viď obrázok). Ak chcete vrátiť súbor tak ako ho máte uložený vo stage, slúži na to príkaz git checkout <file>. Najlepšie vysvetlenie podá obrázok.

Reset checkout - Git

Dnes sa jednalo o trošku dlhší článok. Nabudúce sa pozrieme prácu s vetvami, vymoženosť, bez ktorej sa väčšie projekty nezaobídu.

V nasledujúcom kvíze, Kvíz - Princípy, inštalácie a základy Gitu, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Predchádzajúci článok
Git - Základy
Všetky články v sekcii
Git
Preskočiť článok
(neodporúčame)
Kvíz - Princípy, inštalácie a základy Gitu
Článok pre vás napísal Patrik Valkovič
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Věnuji se programování v C++ a C#. Kromě toho také programuji v PHP (Nette) a JavaScriptu (NodeJS).
Aktivity