Git
Chapters ▾ 2nd Edition

2.3 Základy práce se systémem Git - Zobrazení historie revizí

Zobrazení historie revizí

Po vytvoření několika revizí[7], nebo pokud jste naklonovali repozitář s existující historií revizí, můžete chtít nahlédnout do historie projektu. Nejzákladnějším a nejmocnějším nástrojem je v tomto případě příkaz git log.

Následující příklady ukazují velmi jednoduchý projekt pojmenovaný simplegit. Můžete ho získat spuštěním

$ git clone https://github.com/schacon/simplegit-progit

Po zadání příkazu git log byste pro tento projekt měli dostat výstup, který vypadá zhruba takto:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

Ve výchozím nastavení a bez dalších parametrů vypíše příkaz git log revize daného repozitáře v obráceném chronologickém pořadí — poslední revize se zobrazí na začátku. Jak vidíte, tento příkaz vypíše všechny revize s jejich kontrolním součtem SHA-1, jménem a e-mailem autora, datem zápisu a zprávou o revizi.

Příkaz git log disponuje velkým množstvím nejrůznějších voleb, díky nimž můžete zobrazit přesně to, co potřebujete. Ukážeme si některé z nejpoužívanějších možností.

Jednou z užitečnějších voleb je -p, která zobrazí rozdíly (diff) provedené v každé revizi. Můžete přidat volbu -2, která omezí výpis pouze na dva poslední záznamy:

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end
\ No newline at end of file

Tato volba zobrazí stejné informace, ale za každým záznamem následuje informace o rozdílech. Je to velmi užitečné při kontrole kódu nebo k rychlému zjištění, co se stalo v posloupnosti revizí, které přidal váš spolupracovník. Ve spojení s příkazem git log můžete použít také celou řadu shrnujících voleb. Pokud například chcete pro každou revizi zobrazit některé stručné statistiky, použijte volbu --stat:

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

Jak vidíte, volba --stat vypíše pod každým záznamem revize seznam změněných souborů, kolik souborů bylo změněno (changed) a kolik řádků bylo v těchto souborech vloženo (insertions) a smazáno (deletions). Na konci výpisu se zároveň objeví souhrn těchto informací.

Další opravdu užitečnou volbou je --pretty. Změní výstup logu na jiný než výchozí formát. K dispozici máte několik přednastavených možností. Hodnota oneline vypíše všechny revize na jednom řádku, což oceníte při prohlížení velkého množství revizí. Dále se nabízejí hodnoty short, full a fuller (zkrácený, plný, úplný), které zobrazují výstup přibližně ve stejném formátu, avšak s více či méně podrobnými informacemi:

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

Nejzajímavější možností je předpis format, který vám umožní předepsat vlastní formát výstupu logu. Je to užitečné zejména v situaci, kdy generujete výstup pro strojové zpracování — formát předepisujete explicitně, takže máte jistotu, že se s aktualizací Gitu nezmění:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit

Tabulka Užitečné volby pro git log --pretty=format uvádí některé z užitečnějších značek, které předpis format akceptuje.

Table 1. Užitečné volby pro git log --pretty=format
Parametr Popis výstupu

%H

Otisk revize (H jako hash)

%h

Zkrácený otisk revize

%T

Otisk stromu (T jako tree)

%t

Zkrácený otisk stromu

%P

Otisky rodičovských revizí (P jako parent)

%p

Zkrácené otisky rodičovských revizí

%an

Jméno autora (author name)

%ae

E-mail autora (author e-mail)

%ad

Datum autora (formát respektuje --date=volba)

%ar

Datum autora, relativní

%cn

Jméno autora revize (committer name)

%ce

E-mail autora revize (committer e-mail)

%cd

Datum autora revize (committer date)

%cr

Datum autora revize, relativní

%s

Předmět (subject)

Možná se ptáte, jaký je rozdíl mezi autorem a autorem revize. Autor (author) je osoba, která práci původně napsala, zatímco autor revize (committer) je osoba, která tuto práci naposled použila. Pokud tedy pošlete záplatu k projektu a někdo z užšího týmu [8] ji použije, získáte zásluhu oba — vy, jako autor, i daný člen týmu, jako autor revize. Uvedený rozdíl si blíže vysvětlíme v kapitole Distribuovaný Git.

Parametry oneline a format jsou zvlášť užitečné ve spojení s další možností log`u -- parametrem `--graph. Tato volba přidá pěkný malý ASCII graf, znázorňující vaši větev a historii slučování:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

Tento typ výstupu nás začne víc zajímat, jakmile se v další kapitole začneme zabývat větvením a slučováním.

Uvedli jsme jen několik jednoduchých možností formátování výstupu příkazu git log. Existuje jich mnohem víc. Tabulka Běžné volby příkazu git log uvádí seznam voleb, které jsme zatím probrali, a také pár dalších voleb pro formátování, které se mohou hodit — spolu s popisem toho, jak mění výstup příkazu log.

Table 2. Běžné volby příkazu git log
Volba Popis

-p

Zobrazí záplatu (patch) zahrnutou do každé revize.

--stat

Zobrazí statistiku pro změněné soubory v každé revizi.

--shortstat

Zobrazí pouze řádek změněno/vloženo/smazáno z příkazu --stat.

--name-only

Za informacemi o revizi zobrazí seznam změněných souborů.

--name-status

Zobrazí seznam dotčených souborů spolu s informací přidáno/změněno/smazáno.

--abbrev-commit

Zobrazí jen několik prvních znaků kontrolního součtu SHA-1 místo všech 40.

--relative-date

Zobrazí datum v relativním formátu (např. „2 weeks ago“, tj. před 2 týdny) místo data v úplném tvaru.

--graph

Zobrazí vedle výstupu logu ASCII graf větve a historii slučování.

--pretty

Zobrazí revize v alternativním formátu. Parametry příkazu jsou oneline, short, full, fuller a format (ve kterém uvedete svůj vlastní formát).

Omezení výstupu logu

Kromě voleb pro formátování výstupu akceptuje příkaz git log celou řadu užitečných omezujících voleb — tj. takových, které umožní zobrazit jen podmnožinu revizí. S jednou takovou volbou už jsme se setkali — šlo o volbu -2, která zobrazí pouze dvě poslední revize. Můžete dokonce zadat -<n>, kde n je libovolné celé číslo. Povede to k zobrazení posledních n revizí. Ve skutečnosti ji asi nebudete využívat příliš často, protože Git standardně posílá výstup přes stránkovač, takže se najednou zobrazí jen jedna stránka logu.

Naopak velmi užitečné jsou volby pro vymezení času, jako --since a --until („od“ a „do“). Například následující příkaz zobrazí seznam všech revizí pořízených za poslední dva týdny (2 weeks):

$ git log --since=2.weeks

Tento příkaz pracuje s velkým množstvím formátů. Můžete zadat konkrétní datum ("2008-01-15") nebo relativní datum, jako je "2 years 1 day 3 minutes ago" (před 2 roky, 1 dnem a 3 minutami).

Ze seznamu také můžete vyfiltrovat revize, které odpovídají určitým vyhledávacím kritériím. Volba --author vám umožní filtrovat výpisy podle zadaného autora, volbou --grep můžete ve zprávách k revizi hledat klíčová slova. (Pokud chcete předepsat současnou platnost voleb --author a --grep, musíte přidat --all-match, jinak příkaz propustí revize vyhovující i jedné z nich.)

Dalším opravdu užitečným filtrem je volba -S, které zadáme nějaký řetězec. Způsobí, že se zobrazí jen revize se změnami kódu, kdy byl zadaný řetězec přidán nebo odstraněn. Pokud například chcete zjistit poslední revizi, kdy byl přidán nebo odstraněn odkaz na určitou funkci, můžete zavolat:

$ git log -Sjmeno_funkce

Poslední opravdu užitečná volba pro git log spočívá ve filtrování podle zadané cesty. Jestliže zadáte název adresáře nebo souboru, výstup logu omezíte na revize, které provedly změnu v těchto souborech. Cesta je vždy posledním parametrem a většinou jí předcházejí dvě pomlčky (--) , jimiž je oddělena od ostatních parametrů.

Tabulka Volby pro omezení výstupu příkazu git log uvádí přehled již zmíněných a několika dalších voleb.

Table 3. Volby pro omezení výstupu příkazu git log
Volba Popis

-(n)

Zobrazí pouze posledních n revizí.

--since, --after

Omezí výpis na revize zapsané po zadaném datu.

--until, --before

Omezí výpis na revize zapsané před zadaným datem.

--author

Zobrazí pouze revize, u kterých autor příspěvku odpovídá zadanému řetězci.

--committer

Zobrací pouze revize, u kterých autor revize odpovídá zadanému řetězci.

--grep

Zobrazí pouze revize, které ve zprávě k revizi obsahují zadaný řetězec.

-S

Zobrazí pouze revize, které přidaly nebo odebraly kód se zadaným řetězcem.

Pokud například chcete zjistit, které revize upravující testovací soubory v historii zdrojového kódu Gitu začlenil a zapsal Junio Hamano v říjnu 2008, můžete zadat následující příkaz:

$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

Z téměř 40 tisíc revizí v historii zdrojového kódu Gitu zobrazí příkaz 6 záznamů, které odpovídají zadaným kritériím.