Расширенный журнал Git
Любая система управления версиями предназначена для записи изменений в коде. Благодаря такой записи можно просмотреть историю проекта, чтобы узнать, кто и что сделал, выяснить, откуда появились баги, и отменить изменения, вызвавшие проблемы. Но чтобы воспользоваться этими данными, нужна возможность навигации по истории. Именно для этого и предназначена команда git log.
Вы уже наверняка освоили вывод коммитов с помощью команды git log. Теперь пора научиться передавать в git log дополнительные параметры для уточнения результатов.
Можно выделить две разновидности расширенных возможностей git log: форматирование представления каждого коммита и фильтрация коммитов в выводе. Вместе они позволяют найти в истории проекта любую интересующую вас информацию.
Форматирование вывода команды log
Прежде всего в этой статье мы рассмотрим множество способов отформатировать вывод команды git log
. Для форматирования используются главным образом флаги, с помощью которых можно регулировать объем информации, предоставляемый командой git log
.
Если вас не устраивает формат git log
по умолчанию, то для любого из описанных ниже вариантов форматирования можно создать ярлык с помощью псевдонимов git config
. О настройке псевдонимов читайте в разделе, посвященном команде git config.
Однострочный формат
Флаг --oneline
записывает каждый коммит в одну строку. По умолчанию отображаются только идентификаторы коммитов и первые строки комментариев к ним. Типичный вывод git log --oneline
выглядит следующим образом:
0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base
Это позволяет получить общее представление о проекте.
Связанные материалы
Перемещение полного репозитория Git
СМ. РЕШЕНИЕ
Изучите Git с помощью Bitbucket Cloud
Ссылки
Часто бывает полезно узнать о том, с какими ветками или тегами связаны коммиты. Флаг --decorate
добавляет в вывод команды git log
все ссылки (ветки, теги и т. д.), указывающие на каждый коммит.
Этот флаг совместим с другими параметрами конфигурации. Так, с помощью команды git log --oneline --decorate
можно отформатировать историю коммитов следующим образом:
0e25143 (HEAD, main) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base
Как видите, верхний коммит активен (отмечен указателем HEAD
) и находится на конце ветки main
. На второй коммит указывает другая ветка, под названием feature
. Наконец, четвертый коммит отмечен тегом v0.9
.
Ветки, теги, указатель HEAD
и история коммитов — вот почти полный перечень информации, содержащейся в репозитории Git и дающей комплексное представление о его логической структуре.
Различия
В команду git log
можно добавлять всяческие параметры для просмотра различий, вносимых коммитом. Два самых распространенных варианта — это --stat
и -p
.
Параметр --stat
позволяет просмотреть количество вставок и удалений в каждом файле, который был изменен тем или иным коммитом. (Обратите внимание, что изменение строки записывается как одна вставка и одно удаление.) Такая запись полезна, когда нужен краткий обзор изменений, внесенных каждым коммитом. Например, следующий коммит добавил в файл hello.py
67 строк и удалил из него 38 строк:
commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date: Fri Jun 25 17:30:28 2014 -0500
Add a new feature
hello.py | 105 ++++++++++++++++++++++++-----------------
1 file changed, 67 insertion(+), 38 deletions(-)
Количество знаков «+
» и «-
» рядом с именем файла соответствует относительному количеству изменений, внесенных коммитом в файл. Эти сведения упрощают поиск изменений, соответствующих любому из коммитов.
Для просмотра содержимого изменений, внесенных каждым коммитом, передайте команде git log
параметр -p
. Вывод будет содержать полный патч коммита:
commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date: Fri Jun 25 17:31:57 2014 -0500
Fix a bug in the feature
diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")
Если изменений в составе коммита много, вывод получится длинным, и с ним будет неудобно работать. Обычно из всего списка изменений в патче интересует какое-то конкретное. В таком случае воспользуйтесь параметром pickaxe.
Сводка по журналу
Команда git shortlog
— специальная разновидность git log
, предназначенная для написания объявлений о релизах. С ее помощью можно сгруппировать коммиты по автору и вывести первые строки всех комментариев к ним. Так сразу становится понятно, кто над чем работал.
Например, если два разработчика сделали пять коммитов в проект, вывод git shortlog
может быть следующим:
Mary (2):
Fix a bug in the feature
Fix a serious security hole in our framework
John (3):
Add the initial code base
Add a new feature
Merge branch 'feature'
По умолчанию команда git shortlog
сортирует выходные данные по имени автора, но их также можно отсортировать по количеству коммитов на автора, добавив параметр -n
.
graphs
Параметр --graph
используется для построения диаграммы из символов ASCII, отражающей структуру веток в истории коммитов. Обычно его используют в сочетании с командами --oneline
и --decorate
, чтобы обозначить связи между коммитами и ветками:
git log --graph --oneline --decorate
Ниже показан вывод команды для простого репозитория всего с двумя ветками:
* 0e25143 (HEAD, main) Merge branch 'feature'
|\
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base
Звездочки показывают принадлежность коммитов к той или иной ветке. Так, мы видим, что коммиты 23ad9ad
и 16b36c6
находятся в тематической ветке, а остальные — в ветке main
.
Этот параметр хорош для наглядного представления простых репозиториев. Для проектов со сложной структурой веток лучше использовать полноценные средства визуализации, такие как gitk
или Sourcetree.
Пользовательское форматирование
В остальных случаях для форматирования вывода git log
можно использовать параметр --pretty=format:"<строка>"
. Он позволяет отобразить коммиты так, как вам нужно, с помощью заполнителей типа printf
.
Так, например, символы %cn
, %h
и %cd
в следующей команде будут заменяться соответственно на имя разработчика, сокращенный хеш коммита и дату разработчика.
git log --pretty=format:"%cn committed %h on %cd"
Таким образом, каждый коммит примет следующий формат:
John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500 John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500 Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500 John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500
Весь список заполнителей можно посмотреть в разделе Pretty Formats (Форматы pretty) на странице руководства по команде git log
.
С помощью параметра --pretty=format:"<строка>"
удобно не только просматривать исключительно то, что вас интересует, но и передавать вывод git log
другой команде.
Фильтрация истории коммитов
Научиться форматировать представление коммитов с помощью git log
— только полдела. Нужно еще освоить перемещение по истории коммитов. Остаток этой статьи посвящен продвинутым способам поиска конкретных коммитов в истории проекта с помощью команды git log
. Каждый из них можно сочетать с любым из параметров форматирования, описанных выше.
По количеству
Самый простой вариант фильтрации для git log
— ограничить количество отображаемых коммитов. Если вас интересуют только последние несколько коммитов, нет необходимости просматривать все.
Выходные данные можно ограничить, добавив в git log
параметр -
. Так, следующая команда вернет только последние три коммита.
git log -3
По дате
Если вы ищете коммит, относящийся к определенному периоду, можно использовать флаги --after
или --before
, чтобы отфильтровать коммиты по дате. Оба флага принимают различные форматы даты в качестве параметра. Например, в вывод следующей команды попадут только коммиты, созданные после 1 июля 2014 года (включительно):
git log --after="2014-7-1"
Можно также передать команде относительные ссылки, например 1 week ago
(1 неделю назад) или yesterday
(вчера):
git log --after="yesterday"
Чтобы найти коммиты, созданные в промежутке между двумя датами, можно использовать оба флага, --before
и --after
, и указать соответствующие даты в качестве их значений. Так, для просмотра всех коммитов, добавленных с 1 по 4 июля 2014 года, используйте следующую команду:
git log --after="2014-7-1" --before="2014-7-4"
Если изменений в составе коммита много, вывод получится длинным, и с ним будет неудобно работать. Обычно из всего списка изменений в патче интересует какое-то конкретное. В таком случае воспользуйтесь параметром pickaxe.
По автору
Если вас интересуют только коммиты, созданные конкретным пользователем, воспользуйтесь флагом --author
. Он принимает регулярные выражения и возвращает все коммиты, автор которых соответствует указанному значению. Если вы точно знаете, кого ищете, то вместо регулярного выражения можно использовать обычную строку:
git log --author="John"
Эта команда покажет все коммиты, в имени автора которых есть слово John (Джон). Точное совпадение необязательно — достаточно, чтобы имя содержало указанную фразу.
Можно также создавать сложные поисковые запросы с помощью регулярных выражений. Например, следующая команда позволит найти коммиты, автором которых является Mary (Мэри) или John (Джон).
git log --author="John\|Mary"
Обратите внимание, что адрес электронной почты также относится к имени автора, поэтому этот параметр можно использовать и для поиска по адресу.
Если в вашем рабочем процессе роли авторов и разработчиков разделены, для поиска коммитов по именам разработчиков можно таким же образом использовать флаг --committer
.
По комментарию
Для фильтрации коммитов по комментариям используется флаг --grep
. Он работает точно так же, как флаг --author
, описанный выше, только значения сопоставляются не с именем автора, а с комментарием к коммиту.
К примеру, если команда добавляет в комментарий к каждому коммиту соответствующие номера задач, можно использовать следующую команду для вывода всех коммитов, связанных с нужной задачей:
git log --grep="JRA-224:"
Можно также передать команде git log
параметр -i
: в этом случае различие в регистрах при сопоставлении будет игнорироваться.
По файлу
Иногда нужно найти только изменения, внесенные в конкретный файл. Чтобы просмотреть историю, связанную с файлом, достаточно указать путь к нему. Так, следующая команда вернет все коммиты, посредством которых был изменен файл foo.py
или bar.py
:
git log -- foo.py bar.py
Параметр «--
» указывает команде git log
на то, что последующие аргументы — это пути к файлам, а не имена веток. Если вы уверены, что перепутать путь с веткой невозможно, параметр «--
» можно опустить.
По содержанию
Можно также искать коммиты, которые добавляют или удаляют определенную строку исходного кода. Эта операция называется pickaxe и задается выражением -S"<строка>"
. Например, чтобы узнать, когда строка Hello, World! (Привет, мир!) была добавлена в любой из файлов проекта, используйте команду:
git log -S"Hello, World!"
Если вместо строки для поиска используется регулярное выражение, измените флаг на -G"<регулярное выражение>"
.
Это очень мощное средство отладки, поскольку с его помощью можно найти все коммиты, влияющие на отдельную строку кода. Можно даже узнать, когда строка была скопирована или перемещена в другой файл.
По диапазону
Чтобы просмотреть коммиты из определенного диапазона, укажите его в команде git log
. Диапазон указывают в следующем формате, где <с>
и <по>
представляют собой ссылки на коммиты:
git log ..
Эта команда особенно полезна, если вы используете в качестве параметров ссылки на ветки, и позволяет без труда вывести различия между двумя ветками. Рассмотрим следующую команду:
git log main..feature
Диапазон main..feature
включает все коммиты, принадлежащие к ветке feature
, но не к ветке main
. Иными словами, он показывает, что нового появилось в ветке feature
с момента создания форка от ветки main
. Наглядно это можно представить так:
Обратите внимание, что если поменять местами границы диапазона (feature..main
), то будут выведены все коммиты, присутствующие в main
, но отсутствующие в feature
. Если команда git log
возвращает коммиты для обоих рассмотренных диапазонов, значит, истории веток разошлись.
Фильтрация коммитов слияния
По умолчанию вывод git log
включает коммиты слияния. Но если ваша команда придерживается политики «только слияние» (то есть объединяет восходящие изменения с тематическими ветками, вместо того чтобы перебазировать тематические ветки на вышестоящие), в истории проекта появляется много побочных коммитов слияния.
Эти коммиты слияния можно исключить из вывода git log
, указав флаг --no-merges
:
git log --no-merges
И наоборот, если вас интересуют только коммиты слияния, используйте флаг --merges
:
git log --merges
Он возвращает все коммиты, у которых есть как минимум два родителя.
Резюме
Надеюсь, теперь вы сможете уверенно пользоваться расширенными параметрами git log
для форматирования выходных данных и фильтрации отображаемых коммитов. Это позволит извлекать из истории проекта ровно то, что вам нужно.
Новые навыки станут важным дополнением к вашему инструментарию Git, однако не забывайте, что git log
часто используют вместе с другими командами. Обычно найденный коммит передают команде git checkout
, git revert
или другому инструменту, позволяющему воздействовать на историю коммитов. Поэтому не останавливайтесь на достигнутом и продолжайте изучать расширенные возможности Git.
Поделитесь этой статьей
Следующая тема
Рекомендуемые статьи
Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.