Итак, Вы создали несколько фиксаций текущего состояния проекта (в процессе работы над проектом выполнили несколько раз команду git commit), или Вы склонировали репозиторий с существующей историей фиксаций. В такой ситуации возможно Вам может понадобится посмотреть назад, чтобы увидеть, как происходил процесс разработки. Самый мощный инструмент для этого - команда git log (здесь приведен перевод статьи [1]).
Примечание: фиксация - это выполненная команда git commit -m комментарий.
В качестве примера будет использоваться очень простой проект под названием "simplegit". Чтобы получить проект, запустите команду git clone:
$ git clone https://github.com/schacon/simplegit-progit
Перейдите в каталог проекта simplegit-progit командой cd simplegit-progit, и запустите команду git log. Будет отображено примерно следующее:
$ git log
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
По умолчанию, без дополнительных аргументов, git log перечислит фиксации (commit-ы, которые были сделаны в этом репозитории) в обратном порядке по хронологии, т. е. последним в списке будет самый первый commit. Как можно видеть, эта команда выводит каждый commit вместе с его контрольной суммой (хешем) SHA-1, именем автора и его email, датой фиксации и сообщением commit.
Для команды git log существует большое количество вариантов опций, что позволяет выводить историю фиксаций именно так, как это необходимо. Здесь будет показано несколько самых популярных вариантов использования git log.
Одна из самых полезных опций это -p или --patch, которая показывает различия (вывод патча), введенного с каждым commit. Вы можете также ограничить количество отображаемых записей лога, как например использовать -2, чтобы показать только последние 2 записи.
$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.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@gmail.com"
s.summary = "A simple gem for using Git in Ruby code."
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
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
Опция -p -2 отобразит ту же самую информацию, но вместе с различиями, выводимыми после каждого элемента лога. Это очень полезно для обзора кода, или для понимания, что происходило во время серии следующих друг за другом commit-ов, которые сделали либо Вы, либо тот кто вместе с Вами работает в команде. Также с командой git log можно использовать несколько опций суммирования. Например, если нужно вывести некоторую сокращенную статистику для каждого элемента лога, можно применить опцию --stat:
$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.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@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
lib/simplegit.rb | 5 -----
1 file changed, 5 deletions(-)
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.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 для этой опции выводит каждый commit в одной строке, что полезно, когда надо вывести много commit-ов, чтобы просмотреть их хеши и сообщения:
$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD) changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
Дополнительно значения short, full и fuller создают вывод примерно в том же формате, но с большим или меньшим количеством информации соответственно.
Очень интересна опция format, которая позволит вывести log в произвольном (почти) формате. Это особенно полезна, когда нужно сгенерировать вывод для последующего машинного парсинга, потому что в этом случае формат будет явно указан, и заранее известно, что формат вывода не поменяется с обновлениями Git:
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 14 years ago : changed the version number
085bb3b - Scott Chacon, 14 years ago : removed unnecessary test code
a11bef0 - Scott Chacon, 14 years ago : first commit
Ниже приведены некоторые наиболее полезные спецификаторы git log --pretty=format.
Таблица 1. Полезные спецификаторы опции --pretty=format.
Специф. |
Описание вывода |
%H |
Хеш фиксации. |
%h |
Сокращенный кусок хеша фиксации (7 HEX-символов). |
%T |
Дерево хешей. |
%t |
Дерево сокращенных хешей. |
%P |
Хеши родительских фиксаций. |
%p |
Сокращенные родительские хеши. |
%an |
Имя автора. |
%ae |
Email автора. |
%ad |
Дата автора (формат соответствует --date=опция). |
%ar |
Относительная дата автора. |
%cn |
Имя создавшего commit. |
%cd |
Дата создателя commit. |
%cr |
Относительная дата создателя commit. |
%s |
Subject, предмет элемента истории commit. |
Возможно, Вам будет интересно, в чем разница между author и committer. Персона author это тот, кто изначально выполнил работу, в то время как committer это тот, кто последний применил изменения. Таким образом, если Вы отправили патч для проекта, и один из основных владельцев проекта просмотрел этот патч, одобрил и применил, то Вы оба будете упомянуты в логе - Вы как author, и владелец проекта как committer. Более подробно это различие рассмотрено в статье [2].
Значения oneline и format для опции --pretty в частности полезны вместе с другой опцией --graph для команды git log. Это опция добавляет небольшой поясняющий граф ASCII, показывающий историю ветвлений (branch) и слияний (merge) проекта:
$ 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
Мы рассмотрели только некоторые простые опции вывода и форматирования лога репозитория, на самом деле этих опций гораздо больше. В следующей таблице перечислены параметры git log, которые мы уже рассматривали, а также некоторые другие общие параметры форматирования, которые могут быть полезны в контексте изменения вывода команды log.
Таблица 2. Общие опции для команды git log.
Опция |
Описание |
-p |
Показать исправления (patch), введенные каждой фиксацией (commit-ом). |
--stat |
Показать статистику для файлов, измененных каждой фиксацией. |
--shortstat |
Показать только строки изменения, добавления, удаления из команды --stat. |
--name-only |
Показать список файлов, модифицированных после фиксации. |
--name-status |
Показать также список файлов, на которые повлияли добавления, модификации, удаления в фиксации. |
--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]
В дополнение к опциям вывода и форматирования у git log есть несколько полезных ограничивающих вывод опций. Они позволяют вывести определенное подмножество из истории commit. Выше уже была показана опция -2, которая показывает только последние два commit. Вместо 2 можно указать любое целое число n, задающее сколько надо вывести commit-ов. На практике Вы вряд ли будете часто использовать это (особенно с большими значениями n), потому что Git по умолчанию выводит лог постранично, так что при большом объеме вывода Вы увидите сразу только одну страницу.
Примечание: прокрутка страниц вывода в консоли Bash осуществляется как обычно, клавишами Page Up и Page Down, а выход из просмотра лога происходит по клавише q.
Однако существуют полезные опции, которые ограничивают вывод по времени, такие как --since и --until. Например, следующая команда выведет список commit-ов, сделанных за последние две недели:
$ git log --since=2.weeks
Эта команда работает с большим количеством форматов - можно указать определенную дату как "2008-01-15", или относительную дату, такую как "2 years 1 day 3 minutes ago".
Также Вы можете фильтровать список commit-ов, чтобы они соответствовали некому критерию поиска. Опция --author позволит сделать фильтрацию по определенному автору, и опция --grep позволит выполнить поиск по ключевым словам в сообщениях commit.
Примечание: можно указать несколько экземпляров обоих опций --author и --grep, которые будут ограничивать вывод commit для фиксаций, соответствующих любому из шаблонов --author и любому из шаблонов --grep. Однако добавление опции --all-match дополнительно ограничивает вывод только теми commit-ами, которые соответствуют всем шаблонам --grep.
Другой полезный фильтр опция -S (в просторечии называемой опцией pickaxe, или "кирка"), которая берет на входе строку, и показывает только те commit-ы, которые изменили количество появлений этой строки. Например, если нужно найти последний commit, который добавил или удалил ссылку (вызов) определенной функции, то следует выполнить команду:
Последняя действительно полезная опция для передачи в команду git log в качестве фильтра это путь до файла. Если Вы укажете директорию или имя файла, то сможете ограничить вывод теми commit-ами, которые внесли изменения в указанной директории или в файле. Это всегда последняя опция, и перед ней вставляется двойной дефис (--), чтобы отделить пути от опций:
$ git log -- путь/до/файла
В таблице ниже в качестве справочника перечислены эти и другие опции ограничения вывода git log.
Таблица 3. Опции, которые ограничивают вывод git log.
Опция |
Описание |
-< n> |
Показать только последние n фиксаций. |
--since, --after |
Ограничить список фиксациями, которые были сделаны после указанной даты. |
--until, --before |
Ограничить список фиксациями, которые были сделаны перед указанной датой. |
--author |
Показать только те фиксации, у которых имя автора совпадает с указанным. |
--committer |
Показать те фиксации, у которого имя фиксировавшего совпадает с указанным. |
--grep |
Показать только те фиксации, у которых сообщение commit содержит указанную строку. |
-S |
Показать только те фиксации, которые показывают добавление или удаление кода, содержащего указанную строку. |
Например, если Вы хотите увидеть, какие commit-ы изменили тестовые файлы в истории исходного кода Git, которые были зафиксированы Junio Hamano в октябре 2008 года, и которые не были фиксациями слияния (not merge commits), то можете ввести команду наподобие следующей:
$ 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
Из почти 40000 commit-ов в истории фиксаций исходного кода эта команда покажет только 6, которые соответствуют указанному критерию.
Совет, как не показывать фиксации слияния (merge commits): в зависимости от рабочего процесса в Вашем репозитории может быть ситуация, что значительный процент фиксаций был просто фиксациями слияния, что обычно не очень информативно в выводе лога. Чтобы не отображать фиксации слияния в команде git log, просто добавьте к ней опцию --no-merges.
[Ссылки]
1. Git Basics Viewing the Commit History site:git-scm.com. 2. Distributed Git Distributed Workflows site:git-scm.com. 3. Git Basics Undoing Things site:git-scm.com. 4. Git: кодирование символов для сообщений commit. 5. Git: как восстановить потерянный commit? 6. Руководство по команде git log. |