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

Хеш дерева

%t

Скорочений хеш дерева

%P

Хеши батьків

%p

Скорочені хеши батьків

%an

Ім’я автора

%ae

Поштова адреса автора

%ad

Дата автора (формат враховує опцію --date=option)

%ar

Відносна дата автора

%cn

Ім’я користувача, що створив коміт

%ce

Поштова адреса фіксатора

%cd

Дата фіксатора

%cr

Відносна дата фіксатора

%s

Тема

Вам може стати цікаво в чому різниця між автором та творцем коміту. Автор це людина, що спочатку зробила роботу, тоді як фіксатор — це людина, яка востаннє застосувала роботу. Отже, якщо ви відправили латку до проекту та один з програмістів ядра застосує її, ви обидва будете згадані — ви як автор, а програміст ядра як творець коміту. Ми більше про це поговоримо у Розподілений Git.

Опції oneline і format особливо корисні з іншою опцією log, що називається --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

Цей тип виводу стане цікавішим, коли ми будемо розповідати про гілки та злиття у наступному розділі.

Це тільки декілька простих опцій формату виводу git log — їх набагато більше. Розповсюджені опції git log наводить опції, про які ми вже розповідали, та деякі інші розповсюджені опції формату, що можуть бути корисними, з поясненням того, як вони змінюють вивід команди log.

Table 2. Розповсюджені опції git log
Опція Опис

-p

Показує зміни файлів кожного коміту

--stat

Показує статистику змінених файлів для кожного коміту.

--shortstat

Відображає тільки рядок зміни/вставки/видалення з опції --stat.

--name-only

Показує список змінених файлів після інформації про коміт.

--name-status

Показує список змінених файлів з інформацією додано/змінено/видалено.

--abbrev-commit

Показує тільки перші декілька символів SHA-1 суми замість усіх 40.

--relative-date

Відображає дату у відносному форматі (наприклад, “2 тижня тому”) замість використання повного формату дати.

--graph

Відображає ASCII граф історії гілок та зливань поряд зі звичайним виводом.

--pretty

Показує коміти в альтернативному форматі. Можливі значення: online, short, full, fuller та format (якому задаєте свій власний формат).

--oneline

Скорочення для опцій --pretty=oneline --abbrev-commit.

Обмеження виводу журналу

На додаток до опцій, що контролюють формат виводу, git log також приймає декілька корисний обмежувальних опцій — тобто опцій, що дозволяють вам показувати тільки підмножину комітів. Ви вже бачили одну таку опцію: -2, що відображає тільки останні два коміти. Насправді, ви можете використати -<n>, де n це будь-яке ціле число, щоб показати останні n комітів. Однак навряд чи ви будете використовувати це часто, адже Git зазвичай передає весь свій вивід переглядачу, отже ви бачите тільки одну сторінку журналу за раз.

Втім, опції обмеження по часу, такі як --since (від) та --until (до) дуже корисні. Наприклад, ця команда отримає список комітів за останні два тижні:

$ git log --since=2.weeks

Ця команда працює з різноманітними форматами — ви можете задати точну дату, наприклад "1991-08-24", чи відносну дату, наприклад "2 years 1 day 3 minutes ago".

Ви також можете відсіювати список комітів, що відповідають якомусь критерію пошуку. Опція --author дозволяє вам відбирати по заданому автору, а опція --grep дозволяє вам шукати ключові слова в повідомленнях комітів.

Note

You can specify more than one instance of both the --author and --grep search criteria, which will limit the commit output to commits that match any of the --author patterns and any of the --grep patterns; however, adding the --all-match option further limits the output to just those commits that match all --grep patterns. Ви можете додати більш ніж одну пошукову опцію --author та --grep. Тоді вивід буде обмежено тими комітами, що відповідають будь-якому з шаблонів --author чи будь-якому з шаблонів --grep. Втім, якщо додати опцію --all-match, то буде показано лише ті коміти, що відповідають усім шаблонам --grep.

Інша дійсно корисна опція -S (неформально відома під назвою “кирка” (pickaxe)) приймає рядок та відображає лише ті коміти, що змінили кількість входжень цього рядка у зміст файлів. Наприклад, якщо ви бажаєте знайти останній коміт, що додав чи видалив посилання на певну функцію, вам варто викликати:

$ git log -S function_name

Остання дійсно корисна опція, яку можна передати до git log — це шлях. Якщо ви зазначите директорію або ім’я файлу, ви можете обмежити вивід до комітів, що змінювали ці файли. Це завжди остання опція та зазвичай перед нею ставлять подвійний дефіс (--) щоб відділити шляхи від опцій.

У Опції для обмеження виводу git log ми перелічили ці та ще декілька інших розповсюджених опцій для довідки.

Table 3. Опції для обмеження виводу git log
Опція Опис

-<n>

Показати тільки останні n комітів

--since, --after

Обмежитись комітами, що були створені після переданої дати.

--until, --before

Обмежитись комітами, що були створені до переданої дати.

--author

Показати тільки ті коміти, автор яких збігається із переданим.

--committer

Показати тільки ті коміти, фіксатор яких збігається із переданим

--grep

Показати тільки ті коміти, повідомлення яких містить рядок.

-S

Показати тільки ті коміти, в яких додали або видалили рядок, що містить переданий рядок.

Наприклад, якщо ви бажаєте побачити, в яких комітах були змінені тестові файли в коді Git, що були збережені Junio Hamano у жовтні 2008 року і не є комітами злиття, ви можете виконати таку команду:

$ 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

З приблизно 40000 комітів в історії коду Git, ця команда відображає тільки 6, що задовольняють цим критеріям.

Tip
Приховування комітів злиття

Залежно від процесу роботи у вашому сховищі, цілком можливо, що чималий відсоток комітів у вашій історії є лише комітами злиття, що зазвичай не містять цікавої інформації. Щоб вони не засмічували вивід історії журналу, просто додайте опцію --no-merges.