4. díl - Git - Zkoumání historie

Software Git Git - Zkoumání historie

V minulém díle jsme si něco řekli o základech Gitu. Dnes si ukážeme, jak můžeme k jednotlivým commitům přistupovat. S tím souvisí prohledávání historie, jedna z věcí, ve které Git vyniká.

Pojmenování commitů

V Gitu se na commit můžeme odkazovat několika způsoby. Těmito odkazy poté můžeme jednoznačně identifikovat konkrétní commit. Jsou to:

  • 40-ti znakový hash commitu
  • Jméno větve
  • Jméno tagu

Hash commitu

Jak jsme si řekli v minulém díle, každý commit je definován svým hashem. Jedná se o 40-ti místné hexadecimální číslo, které zjistíte buď z GUI nebo příkazem git log nebo git show. Toto číslo je jedinečné pro každý commit. Pro identifikaci commitu ovšem nemusíte toto číslo psát celé, stačí pouze jeho několik prvních znaků. Tentokrát si pro demo naklonujeme repositář 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

Jméno větve

K větvím jsme se ještě nedostali, budeme je probírat v příštím díle. Každá větev se skládá alespoň z jednoho commitu. I když vytvoříte nový lokální repositář a uděláte první commit, vytvoříte tím hlavní větev „master“. Seznam větví zobrazíte příkazem git branch. Jako odkaz můžeme použít právě jméno této větve, přitom větev pouze odkazuje na poslední commit, který byl v dané větvi vytvořen. Z toho plyne, že jestliže jste nevytvářeli nové větve, větev „master“ bude ukazovat na poslední commit, který jste udělali.

$ git branch
* master

V tuto chvíli se vypíše pouze větev master, protože při klonování repositáře dochází ke klonování pouze jediné větve. Jedná se o tu větev, kterou vývojáři zveřejnili. To ovšem neznamená, že projekt nemůžeme mít více větví, pouze je mají vývojáři lokálně u sebe.

Tagy

Tagy můžeme přidávat libovolně ke kterémukoliv commitu. Můžeme si jimi označit důležitá místa v historii, nové verze, opravy důležitých chyb a cokoliv jiného. Všechny tagy v projektu vypíšeme příkazem git tag. Přitom jsou tagy seřazeny od nejstarších k novější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 dělíme na dvě verze, lehké (lightweight) a anotované (annotated). Lehký tag se velmi podobá větvi, pouze s tím rozdílem, že se nepřemisťuje. Tedy slouží pouze jako odkaz na určitý commit. Anotovaný tag už je ovšem něco jiného, jedná se o plnohodnotný objekt, srovnatelný s commitem. Obsahuje všechny identifikační informace jako commit (jméno autora, čas, hash). Můžeme k němu také přidat zprávu.

Pro vytvoření lehkého tagu nám stačí pouze přejít na commit, který chceme označit a zadat příkaz git tag jmenoTagu. Pro vytvoření anotovaného tagu přidáme možnost –a, tedy příkaz bude podle vzoru git tag –a jmenoTagu –m „Zprava k tagu“. Opět si ukážeme ukázku.

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

Přechod mezi commity

K přechodu mezi commity slouží příkaz git checkout. Ten vás přesune na místo, které jste mu zadali jako parametr. Zároveň s tím aktualizuje pracovní složku do stavu, jak vypadala právě v tom určitém commitu. Na tomto místě poté můžeme vytvářet nové větve, přidávat tagy nebo i upravovat commit. Po provedení práce se dostaneme zpátky příkazem git checkout master. Tím přepneme na vrchol větve master (tedy na její poslední commit). Je ovšem také možné přesouvat se na tagy, popřípadě v rámci větví. Jak se tedy dostanu 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

Co nám výstup říká? V prvním odstavci nás informuje o tom, že jsme přešli do „detached HEAD“ stavu. Pro nás to znamená, že můžeme dělat cokoliv, aniž bychom ovlivnili jakékoliv jiné větve. Zároveň ale musíme počítat s tím, že jakmile přejdeme na jiné místo, všechny změny se zruší. V druhém odstavci nám Git říká, jak tento problém můžeme vyřešit. Zavoláním git checkout s parametrem -b. Tím se vlastně vytvoří nová větev. O tom ale bude až další článek. Nakonec nám napíše, že jsme aktuálně na commitu s hashem c1be5a5… a vypíše nám jeho popis. Zároveň si všimněte, že se aktualizoval pracovní adresář. Můžete pracovat se soubory stejně jako v době, kdy byl tento commit vytvořen. Pro přejití zpět zadáme git checkout master.

Git log a show

S příkazy git log a git show jsme se již setkali. Git log zobrazí historii commitů, zatímco git show poslední commit. To ale není všechna jejich funkčnost. Git log dokáže zobrazit historii od určitého commitu, mezi dvěma commity apod.

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é způsoby jde samozřejmě také kombinovat. K tomu bych ještě rád zmínil atribut --oneline, který každý commit zobrazí pouze na jednom řádku. Přitom zobrazí pouze začátek hashe commitu a jejich 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 příkazem je git show. Tomu můžeme předat odkaz ke konkrétnímu commitu nebo tagu. Podíváme se tedy na commit b8cb464, který by měl měnit soubor ihex2fw.c.

$ git show b8cb464
commit b8cb464e4a8abc60ad5a43e0375fec8a3c728167
Author: Chris Ruffin <cmruffin@gmail.com>
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.

    [akpm@linux-foundation.org: correctly handle short writes]
    Signed-off-by: Chris Ruffin <cmruffin@gmail.com>
    Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

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

Opět se nám zobrazí základní informace o commitu, poté výpis pokračuje popisem commitu. Poté je hlavička emailu. To je proto, že autoři repositáře musí ověřit, zda se jedná o funkční commit. Kdyby mohl kdokoliv přispívat, každý by si mohl s projektem dělat co chce (mohl by například zanést bug nebo nějaký vir). Proto musí autoři repositáře ověřit, zda se jedná o funkční commit. A právě tato žádost o přidání vlastního commitu do projektu probíhá přes email. Na dalším řádku vidíme, že se změnil pouze soubor ihex2fw. Dále ve výpisu je vypsané co se změnilo (řádek označený minus byl smazán, zatímco řádek označený + byl přidán). Takto můžete projít všechny commity a zjistit, co se kde změnilo, kdy se to změnilo a kdo za změnou stojí.

Rozdíl

Pokud byste ovšem chtěli zobrazit příkaz show mezi dvěma commity, jak jsme to například vypisovali u git log, tak zjistíte, že vás Git nepustí. Pro tento účel existuje samostatný příkaz git diff. Git diff bez parametrů vypíše rozdíl mezi pracovní složkou a stagem (indexem). Příkaz git diff HEAD vypíše rozdíl mezi posledním commitem a pracovní složkou. Kromě toho můžeme jako parametr předat stejný řetězec, jako u logu.

Pokud chceme měnit pracovní složku, slouží k tomu také několik příkazů. Jestliže jste editovali soubor a chcete vrátit jeho změny, tak jak byly u posledního commitu, slouží k tomu příkaz git reset HEAD <file> nebo git checkout HEAD <file> (záleží na situaci, viz obrázek). Pokud chcete vrátit soubor tak jak jej máte uložený ve stage, slouží k tomu příkaz git checkout <file>. Nejlepší vysvětlení podá obrázek.

Reset checkout

Dnes se jednalo o trošku delší článek. Příště se podíváme práci s větvemi, vymoženost, bez které se větší projekty neobejdou.


 

  Aktivity (1)

Článek pro vás napsal patrik.valkovic
Avatar
Věnuji se programování v C++ a C#. Kromě toho také programuji v PHP (Nette) a JavaScriptu.

Jak se ti líbí článek?
Celkem (9 hlasů) :
4.777784.777784.777784.777784.77778


 


Miniatura
Předchozí článek
Git - Základy
Miniatura
Všechny články v sekci
Git
Miniatura
Následující článek
Git - Rozděluj a panuj

 

 

Komentáře

Avatar
jadana
Člen
Avatar
jadana:

dal jsem z za plný počet bodů :-)
proč?
protože sám používám GIT i na lokálech a komituje mi to ještě na server, co mi běží na neveřejné IP.
A proč za plno?
kdo se naučí komitovat si svoji práci, má ušetřenu spoustu času, byť je článek hodně povrchní...
chtělo by to pro newbie trochu více popsat. ale nekonec, máme tu manuály, tak studujeme

 
Odpovědět 3.9.2014 22:49
Avatar
Čamo
Člen
Avatar
Čamo:

Akurát sa učím robiť s Gitom, takže tento seriál sa mi presne hodí. Dúfam, že bude pokračovať.

 
Odpovědět 6.9.2014 23:44
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.