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

    Change version number

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

    Remove unnecessary test

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

    Initial 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

    Change 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

    Remove 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

    Change 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

    Remove 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

    Initial 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 Change version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Remove unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 Initial commit

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

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

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

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

%H

Хеш на къмита

%h

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

%T

Tree хеш

%t

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

%P

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

%p

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

%an

Име на автора

%ae

Имейл на автора

%ad

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

%ar

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

%cn

Име на committer

%ce

Имейл на committer

%cd

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

%cr

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

%s

Съобщение

Може да се запитате каква е разликата между author и committer. Авторът е лицето, което първоначално е писало нещо по дадена задача, докато committer е лицето, което последно е допринесло в нея. Така, ако вие изпратите даден пач към проект и някой от сътрудниците го приложи към проекта, и двамата правите принос — вие като автор и въпросния сътрудник като committer. Ще разгледаме по-подробно това разделение в [ch05-distributed-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 Add 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.

Таблица 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, иначе командата ще показва резултат ако дори и само единият критерий съвпада)

Забележка

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

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

$ git log -S function_name

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

$ git log -- path/to/file

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

Таблица 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-те, които отговарят на критерия.

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

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

scroll-to-top