Close

Расширенный журнал 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

Логотип Bitbucket
СМ. РЕШЕНИЕ

Изучите 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.

Люди сотрудничают друг с другом, используя стену со множеством инструментов

Блог Bitbucket

Рисунок: DevOps

Образовательные программы DevOps

Демонстрация функций в демо-зале с участием экспертов Atlassian

Как инструмент Bitbucket Cloud работает с Atlassian Open DevOps

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up