Git
Chapters ▾ 2nd Edition

2.3 Основи на Git - Преглед на историята на действията

Преглед на историята на действията

След като сте създали няколко къмита, или ако сте клонирали хранилище с налични такива - може да пожелаете да погледнете назад за да видите как се е развивал проекта. Най-простият, но и мощен инструмент за това е командата git log.

Тези примери използват много прост проект наречен “simplegit”. За да го изтеглите, изпълнете

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

След като пуснете git log в този проект, трябва да видите изход подобен на следния:

$ 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

По подразбиране, без аргументи, git log показва промените направени в хранилището в обратен хронологичен ред, най-новите се показват най-горе. Както можете да видите, командата показва всеки къмит с неговата SHA-1 чексума, името и имейла на автора, датата и съобщението на къмита.

Самата команда git log разполага с голям брой различни опции, които да ви помогнат да намерите точно необходимата информация. Ще покажем някои от най-популярните.

Един от най-полезните аргументи е -p или --patch, който показва разликите (patch изхода) настъпили с всеки къмит. Можете да използвате също и -2, което ще ограничи изхода само до последните два къмита:

$ 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

Тази команда показва същата информация, но с разликите директно след всеки елемент от историята. Това е много полезно за преглед на код или за набързо разглеждане на промените настъпили в серия къмити от даден сътрудник. Можете да използвате и серия от статистически параметри с git log. Например, ако искате да видите съкратена статистика за всеки къмит, ползвайте параметъра --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(+)

Както се вижда, параметърът --stat отпечатва след всеки къмит списък на модифицираните файлове, колко от тях са променени и колко редове в тях са добавени и изтрити. Отпечатва се и сумарна информация в края.

Друга наистина полезна опция е --pretty. Това форматира изхода по начин различен от подразбиращия се. Разполагате с няколко избора за ползване. Стойността oneline печата всеки къмит на единичен ред, което е полезно ако търсите в множество къмити. В допълнение, стойностите на аргумента short, full, и fuller показват изхода в почти същия формат, но с по-малко или повече информация съответно:

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

Най-интересната стойност на параметъра е format, която ви позволява сами да укажете формата на изхода. Това е особено полезно, ако се налага да генерирате изход за последваща машинна обработка, защото можете изрично да укажете формата и да сте сигурни, че той ще си остане същия докато версиите на Git се обновяват:

$ 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

Полезни опции за git log --pretty=format показва някои от най-популярните флагове, които format разбира.

Table 1. Полезни опции за git log --pretty=format
Флаг Описание

%H

Хеш на къмита

%h

Съкратен хеш на къмита

%T

Tree хеш

%t

Съкратен Tree хеш

%P

Родителски хешове

%p

Съкратени родителски хешове

%an

Име на author

%ae

Имейл на author

%ad

Дата на author къмит (форматът взема предвид --date=option)

%ar

Релативна дата на author къмит

%cn

Име на committer

%ce

Имейл на committer

%cd

Дата на committer-къмит

%cr

Релативна дата на committer-къмит

%s

Съобщение

Може да се запитате каква е разликата между author и committer. Авторът е лицето, което първоначално е писало нещо по дадена задача, докато committer е лицето, което последно е допринесло в нея. Така, ако вие изпратите даден пач към проект и някой от сътрудниците го приложи към проекта, и двамата правите принос — вие като автор и въпросния сътрудник като committer. Ще разгледаме по-подробно това разделение в Git в разпределена среда.

Аргументите oneline и format са особено полезни в съчетание с друг аргумент, --graph. Това добавя забавна малка ASCII графика, показваща клона и историята на сливанията:

$ 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

Този тип изход става по-интересен, когато навлезем в материята на клоновете (branching) и сливането (merging) в следващата глава.

Но това са само някои прости опции за форматиране на изхода на git log — съществуват и много други. Common options to git log изброява опциите, които вече разгледахме плюс някои други полезни такива, променящи изхода на командата log.

Table 2. Common options to git log
Опция Описание

-p

Показва пача за всеки къмит.

--stat

Показва статистики за файловете променени във всеки къмит.

--shortstat

Показва само changed/insertions/deletions реда от --stat варианта.

--name-only

Показва списък на променените файлове след информацията за къмита.

--name-status

Показва списък на засегнатите файлове ведно с added/modified/deleted детайлите.

--abbrev-commit

Показва само първите няколко символа на SHA-1 чексумата, вместо всичките 40.

--relative-date

Показва датата в релативен формат (например, “2 weeks ago”) вместо в пълния ѝ формат.

--graph

Показва ASCII графика на branch и merge историята до изхода.

--pretty

Показва къмитите в алтернативен формат. Стойностите включват oneline, short, full, fuller, и format (където указвате собствен формат на изхода).

--oneline

Съкращение за --pretty=oneline --abbrev-commit използвани заедно.

Ограничаване на изхода

В допълнение към опциите за формат на изхода, git log поддържа и полезни средства за лимитиране, с които да показвате само част от къмитите. Вече видяхте едно от тях под формата на параметър -2, показващ само последните два къмита. В действителност, можете да ползвате -<n>, където n е произволно число, за да покажете колкото от тях желаете. Практически обаче, това рядко се налага, защото Git по подразбиране странира изхода си, така че да виждате само по един екран в даден момент.

Обаче, опциите за ограничаване по време, като --since и --until, са много полезни. Например, тази команда показва списък от къмитите направени в последните две седмици:

$ git log --since=2.weeks

Тази команда работи с множество формати — можете да укажете специфична дата като "2008-01-15", или релативен период като "2 years 1 day 3 minutes ago".

Можете също да филтрирате списъка с къмити, които съответстват на определен критерий за търсене. Опцията --author позволява да търсите по определен автор и --grep опцията ви позволява да търсите по ключови думи в съобщенията на къмитите. (Отбележете, че ако искате да използвате едновременно и двете опции, трябва да добавите --all-match, иначе командата ще показва резултат ако дори и само единият критерий съвпада)

Note

Можете да укажете повече от една инстанция за --author и --grep критериите, което ще ограничи показваните къмити до всеки, който отговаря на --author и всеки, който отговаря на --grep маските; обаче, добавянето на --all-match опцията допълнително ограничава изхода до само тези, които отговарят на всички --grep маски.

Друг полезен филтър е опцията -S (позната още като “pickaxe” опцията на Git), която приема стринг и показва само тези къмити, които са променили броя на срещанията на този стринг. Ако примерно желаете да намерите последния къмит, който е добавил или премахнал обръщение към специфична функция, можете да изпълните:

$ git log -S function_name

Последната доста полезна опция, която можете да пратите като филтър към git log е път към файл/директория. Ако укажете име на директория или файл, можете да ограничите изхода до къмитите, в които са правени промени по тези специфични файлове. Това винаги трябва да е последен параметър към командата и обикновено се слага префикс от две тирета (--) за разделяне на пътищата от другите параметри.

В таблицата Опции за ограничаване на изхода на git log разглеждаме тези и някои други опции.

Table 3. Опции за ограничаване на изхода на git log
Опция Описание

-<n>

Показва само последните n на брой къмита

--since, --after

Показва само къмитите направени след указаната дата.

--until, --before

Показва само къмитите направени преди указаната дата.

--author

Показва само къмитите, в които авторът съответства на подадения стринг.

--committer

Показва само къмитите, в които committer-ът съответства на подадения стринг.

--grep

Позволява търсене по стринг в commit-съобщението

-S

Позволява търсене по стринг в промените в кода

Например, ако искате да видите кои къмити променили тестови файлове в сорс кода на Git са направени от Junio Hamano през октомври 2008 и това не са merge-къмити, можете да изпълните нещо подобно:

$ git log --pretty="%h - %s" --author='Junio C Hamano' --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

Тази команда филтрира близо 40 хиляди къмита от историята на сорс кода на Git и показва само 6-те, които отговарят на критерия.

Tip
Пропускане на показването на merge къмити

В зависимост от работната последователност, която се използва във вашето хранилище, възможно е голям процент от къмитите в историята да са просто merge къмити, които обикновено не са много информативни. За да забраните показването им, и да опростите историята, просто подайте аргумента --no-merges.