Поиск по сообщению git log --grep

17 декабря 2025
Автор

Олег Марков

Введение

Поиск по истории коммитов — один из самых частых сценариев работы с Git. Очень часто нужно ответить на вопросы:

  • кто добавил эту логику;
  • когда появился конкретный баг;
  • в каком коммите упоминался определенный тикет или задача;
  • где в истории фигурировала фраза fix race condition или FEATURE PAYMENTS.

Для этого в Git есть мощный инструмент — поиск по сообщению коммита с помощью опции --grep в команде git log.

В этой статье вы увидите, как работает git log --grep, как настраивать чувствительность к регистру, использовать регулярные выражения, комбинировать поиск по сообщению с другими фильтрами (--author, --since, --grep + -S и т.д.) и как не попасть в типичные ловушки.


Что делает git log --grep

Основная идея

Опция --grep говорит git log отфильтровать коммиты по содержимому сообщения (subject + body). То есть Git будет просматривать именно текст коммитов: строку заголовка и основное описание, а не измененные файлы и строки кода.

Простейший пример:

git log --grep="BUG-1234"
# Здесь Git покажет только те коммиты,
# в сообщении которых встречается строка "BUG-1234"

Смотрите, я покажу вам, как это воспринимает Git:

  • берется каждое сообщение коммита;
  • к нему применяется поиск по шаблону --grep="...";
  • если сообщение совпало с шаблоном — коммит отображается, иначе пропускается.

Важно понимать: по умолчанию --grep использует регулярные выражения (regexp), а не простой "поиск подстроки" в привычном смысле. Но если вы не используете спецсимволы регулярок (., *, ?, [], ^, $ и т.п.), это фактически будет выглядеть как поиск подстроки.


Базовое использование git log --grep

Поиск по точной подстроке (практически)

Давайте разберемся на простом примере, когда вам нужно найти все коммиты, где в тексте сообщения встречается слово refactor.

git log --grep="refactor"

Как видите, команда:

  • выведет список коммитов с сообщениями, в которых есть refactor (в любом месте сообщения);
  • не учитывает регистр, если включена настройка grep.patternType=basic и не указаны параметры чувствительности. Чтобы точно контролировать регистр, лучше явно задавать флаги, о них поговорим дальше.

Сразу полезный флаг для удобного просмотра:

git log --grep="refactor" --oneline
# --oneline - выводит каждый коммит в одну строку
# удобно для быстрого просмотра результатов поиска

Еще один часто полезный флаг — -p, чтобы сразу увидеть изменения:

git log --grep="refactor" -p
# -p - показывает diff для каждого найденного коммита

Поиск по нескольким словам

Если вы хотите искать сразу несколько разных фраз, можно передать --grep несколько раз:

git log --grep="BUG-" --grep="HOTFIX"
# Здесь будут показаны коммиты, в сообщениях которых
# есть либо "BUG-", либо "HOTFIX"

По умолчанию несколько --grep связываются как логическое "ИЛИ" (OR). То есть коммит попадет в результат, если удовлетворяет хотя бы одному шаблону.

Позже вы увидите, как переключиться на логику "И" (AND).


Управление регистром: учитывать или игнорировать

Флаг -i (ignore case)

Поиск по умолчанию может зависеть от настроек Git, но чтобы не гадать, проще явно использовать флаг -i, который игнорирует регистр:

git log --grep="fix" -i --oneline
# Найдет "fix", "Fix", "FIX" и любые другие варианты

Теперь вы уверены, что не пропустите коммиты из-за разницы в регистре.

Обратный случай — чувствительный к регистру поиск

Если по какой-то причине у вас глобальные настройки заставляют Git игнорировать регистр, можно включить чувствительность к регистру через --regexp-ignore-case=false, но на практике проще настраивать это через конфиг git config или использовать шаблоны регулярок, различающих регистр. Для большинства сценариев достаточно знать и применять флаг -i.


Использование регулярных выражений в --grep

Теперь давайте посмотрим, как использовать силу регулярок, а не только простую подстроку.

Простейший пример с регулярными выражениями

Предположим, вы ведете задачи в таком формате: TASK-123, TASK-456, TASK-789. Вам нужно найти все коммиты, где в сообщении был упомянут любой идентификатор задачи.

git log --grep="TASK-[0-9]\+"
# TASK- + одна или больше цифр
# \+ - квантификатор "один или более" в basic regexp

По умолчанию Git использует "basic" регулярные выражения (BRE), в которых некоторые спецсимволы нужно экранировать с помощью обратного слэша.

Если вам привычнее "extended" регулярные выражения (ERE), можно переключить режим.

Переключение типа регулярок

Git поддерживает несколько типов регулярных выражений через опцию --regexp-type:

  • basic (по умолчанию во многих конфигурациях);
  • extended;
  • perl (PCRE);
  • fixed (поиск буквальной строки).

Пример с расширенными регулярками:

git log --grep="TASK-[0-9]+" --regexp-type=extended
# Здесь "+" уже не нужно экранировать

Пример с perl-совместимыми регулярками:

git log --grep="TASK-(\d{3,5})" --regexp-type=perl
# (\d{3,5}) - 3–5 цифр подряд

Поиск по началу или концу строки

Иногда нужно найти коммиты, у которых заголовок сообщения начинается с определенного префикса. Например, все фиксы:

git log --grep="^fix" --oneline
# Найдет сообщения, где строка начинается с "fix"

Или наоборот — сообщения, заканчивающиеся на ! (например, для breaking changes):

git log --grep="!$" --oneline
# Найдет заголовки/строки, которые заканчиваются на "!"

Поиск по нескольким вариантам в одном шаблоне

Представьте, что вы хотите найти упоминания задач разных типов: BUG-123, TASK-456, FEATURE-789. Можно объединить варианты в один шаблон:

git log --grep="\(BUG\|TASK\|FEATURE\)-[0-9]\+" 
# В basic regexp "или" записывается как \(A\|B\)

Если включить extended-режим, запись упростится:

git log --grep="(BUG|TASK|FEATURE)-[0-9]+" --regexp-type=extended

Теперь Git покажет все коммиты, где в сообщении была ссылка на любую из этих задач.


Комбинация нескольких --grep: логика AND/OR

Поведение по умолчанию — OR

Как уже упоминалось, если вы укажете несколько --grep без дополнительных опций, Git будет использовать логику "ИЛИ":

git log --grep="refactor" --grep="cleanup"
# Показать коммиты, где есть ИЛИ "refactor", ИЛИ "cleanup"

Здесь достаточно совпадения по любому одному шаблону.

Логика AND: флаг --all-match

Если вы хотите найти коммиты, в сообщении которых встречаются сразу все указанные фразы (логика "И"), используйте --all-match.

Давайте посмотрим на примере. Допустим, вам нужны коммиты, в сообщении которых присутствуют и BUG- и database:

git log --grep="BUG-" --grep="database" --all-match
# Будут показаны только те коммиты, в сообщении которых
# одновременно есть и "BUG-" и "database"

Важно: --all-match относится ко всем --grep в команде, но не распространяется, например, на --author или --committer. То есть логика "И" применяется только между шаблонами --grep.


Комбинация --grep с другими фильтрами git log

git log умеет фильтровать коммиты по множеству критериев: автор, дата, файлы, диапазоны коммитов, содержимое изменений и т.д. В реальной работе поиск по сообщению редко используется изолированно — вы почти всегда будете комбинировать --grep с чем-то еще.

Поиск по сообщению и автору

Допустим, вы хотите найти все коммиты, где упоминался тикет PAY-101, и при этом их делал конкретный разработчик:

git log --grep="PAY-101" --author="Иван" --oneline
# Найдет только те коммиты, где:
# - в сообщении есть "PAY-101"
# - автор коммита содержит подстроку "Иван"

Опция --author сама по себе тоже использует регулярные выражения. Можно написать, например:

git log --grep="PAY-101" --author="ivan\.petrov@company\.com"

Поиск по сообщению и диапазону времени

Очень частый сценарий — "найти все коммиты с упоминанием migration за последние 2 недели". Теперь давайте перейдем к примеру:

git log --grep="migration" --since="2 weeks ago" --oneline
# --since - фильтр по дате, всё что новее указанной точки

Можно, наоборот, ограничить историю по верхней границе:

git log --grep="migration" --until="2023-12-31" --oneline

Или использовать обе границы сразу:

git log --grep="migration" --since="2023-12-01" --until="2023-12-31"

Поиск по сообщению и файлам

Если нужно найти коммиты, в которых изменялся конкретный файл и в сообщении фигурировала определенная фраза, можно сочетать --grep с указанием путей.

Например, вас интересуют все коммиты, где обновлялся файл app/config.yml и упоминался redis:

git log --grep="redis" -- app/config.yml
# Обратите внимание:
# после двойного дефиса "--" идут пути к файлам/каталогам

Если путь идет без --, Git может попытаться воспринять его как часть параметров, поэтому принято ставить разделитель --, когда вы указываете файлы.


Отличия --grep от -S и -G (поиск по коду, а не по сообщению)

Иногда разработчики путают --grep с опциями -S и -G, которые ищут по содержимому изменений (diff), а не по тексту сообщения.

Давайте коротко разберем отличие.

--grep — ищет по сообщению

То, о чем идет речь в этой статье, — поиск по тексту сообщения коммита (того, что вы пишете при выполнении git commit).

git log --grep="API change"
# Ищет по заголовку и телу сообщения

-S — поиск по добавленным/удаленным строкам

Опция -S ищет коммиты, в которых была добавлена или удалена строка, содержащая конкретный текст. Она смотрит на diff, а не на сообщение.

git log -S"GetUserByID" -p
# Найдет коммиты, где упоминание "GetUserByID"
# появлялось или исчезало в коде/файлах

-G — поиск по регулярному выражению в изменениях

Опция -G похожа на -S, но принимает на вход регулярное выражение для поиска по измененным строкам.

git log -G"TODO.*remove" -p
# Найдет коммиты, где среди измененных строк
# были строки, соответствующие этому шаблону

Комбинация --grep с -S / -G

Вы можете одновременно фильтровать и по сообщению, и по содержимому изменений. Покажу вам, как это выглядит на практике:

git log --grep="BUG-123" -S"GetUserByID" -p
# Покажет только те коммиты, где:
# - в сообщении есть "BUG-123"
# - и в изменениях фигурировала строка с "GetUserByID"

Такая комбинация полезна, если вы хотите точно найти связку "этот тикет" + "конкретная функция/строка в коде".


Управление форматом вывода при использовании --grep

Чтобы результаты поиска были удобочитаемыми, git log позволяет довольно гибко настраивать формат вывода.

Короткий формат для просмотра списка

Чаще всего после фильтрации по --grep достаточно быстро посмотреть список найденных коммитов. Для этого удобно использовать:

git log --grep="refactor" --oneline --decorate
# --oneline - короткий формат (hash + subject)
# --decorate - показывает ссылки (ветки, теги) на коммит

Полный формат с датой и автором

Если вам важна дата и автор, добавьте флаг --pretty:

git log --grep="PAY-101" --pretty="%h %ad | %an | %s" --date=short
# %h  - короткий hash
# %ad - дата автора
# %an - имя автора
# %s  - заголовок сообщения
# --date=short - формат даты YYYY-MM-DD

Обратите внимание, как этот формат помогает быстро фильтровать глазами историю по нужным признакам.

Отображение только тела сообщений

Если вам интересно именно тело сообщения (body), а не полный лог с diff, можно настроить вывод так:

git log --grep="changelog" --pretty="commit %H%n%n%s%n%n%b%n"
# %H - полный hash
# %s - заголовок
# %b - тело сообщения
# %n - перевод строки

Практические сценарии использования git log --grep

Теперь давайте перейдем к нескольким живым сценариям, с которыми вы точно столкнетесь на практике.

Сценарий 1: поиск коммитов по идентификатору задачи

Предположим, в вашей команде принято указывать ID задачи в заголовке коммита, например:

  • BUG-1234 Fix crash on startup
  • TASK-5678 Implement caching layer

Вы хотите найти все коммиты по задаче BUG-1234:

git log --grep="BUG-1234" --oneline

Если задачи могут упоминаться и в теле (особенно при squash- или merge-коммитах), этого все равно достаточно, потому что --grep смотрит и на заголовок, и на тело.

Сценарий 2: поиск "подозрительных" коммитов

Часто нужно найти "подозрительные" коммиты — например, все hotfix'ы или временные изменения.

git log --grep="hotfix" --grep="temp" --grep="quick fix" --oneline
# Ищем коммиты, где есть хотя бы один из этих маркеров

Если ваша команда договорилась помечать временный код словами WIP или TMP, вы можете отследить все такие коммиты:

git log --grep="WIP" --grep="TMP" --oneline

Сценарий 3: поиск breaking changes по префиксу в сообщении

Допустим, вы используете соглашение, где breaking changes помечаются так:

  • BREAKING: remove legacy v1 API
  • BREAKING: change auth token format

Тогда поиск будет выглядеть так:

git log --grep="^BREAKING" --oneline
# ^BREAKING - заголовок начинается с BREAKING

Так вы можете быстро собрать все потенциально опасные изменения и, например, подготовить release notes.

Сценарий 4: поиск изменений конфигурации или миграций

Нередко нужно быстро найти все коммиты, которые затрагивали миграции БД или конфигурацию.

Если команда придерживается конвенции по сообщениям, например:

  • db: add users table
  • db: change index for payments
  • config: update S3 credentials

То поиск будет таким:

git log --grep="^db:" --grep="^config:" --oneline

Если таких соглашений нет, можно ориентироваться по контрольным словам:

git log --grep="migration" --grep="schema" --oneline

Сценарий 5: анализ истории по конкретной теме за определенный период

Представим, что вам нужно собрать список всех коммитов, связанных с платежами, за последний месяц, чтобы оценить масштаб изменений.

git log --grep="payment" --grep="PAY-" -i \
  --since="1 month ago" \
  --oneline

Здесь мы:

  • ищем по словам payment и PAY- (идентификатор тикетов);
  • игнорируем регистр (-i);
  • ограничиваем поиск последним месяцем.

Производительность и ограничения при использовании --grep

Почему поиск может быть медленным

git log --grep вынужден "прочитать" сообщение каждого коммита в диапазоне, который вы ему задали. На маленьких репозиториях это незаметно, но в больших монорепозиториях с десятками или сотнями тысяч коммитов поиск может занимать ощутимое время.

Несколько практических советов:

  1. Старайтесь ограничивать диапазон поиска:

    • по времени (--since, --until);
    • по ветке (git log main --grep=..., git log release/1.2 --grep=...);
    • по путям (указание подкаталогов, если вас интересует только часть проекта).
  2. Избегайте чрезмерно сложных регулярок, которые тяжелы для обработки.

  3. При необходимости ищите сначала по более общему признаку (например, по тикету), а затем уточняйте поиск.

Когда git log --grep не поможет

Важно помнить: --grep не ищет по содержимому файлов, он смотрит только в текст сообщений коммитов. Поэтому:

  • если нужное слово есть в коде, но не в сообщении — --grep это не найдет (нужны -S или -G);
  • если кто-то сделал коммит без осмысленного сообщения ("fix", "update", "change"), найти такой коммит по смыслу будет трудно.

Лучшие практики использования сообщений коммитов для эффективного grep

Чтобы git log --grep был реально полезен, коммит-месседжи должны быть осмысленными и структурированными. Смотрите, от чего напрямую зависит удобство поиска:

  1. Наличие идентификаторов задач (например, PROJ-123).
  2. Наличие понятного глагола действия (add, fix, refactor, remove).
  3. Единые префиксы для областей системы (db:, auth:, api: и т.п.).

Примеры хорошо структурированных сообщений:

  • PAY-101 fix double charge for recurring payments
  • DB add index for user_id on payments table
  • AUTH refactor token validation logic

Такие сообщения очень удобно искать:

git log --grep="PAY-101" --oneline
git log --grep="^DB " --oneline
git log --grep="^AUTH refactor" --oneline

Если в команде сейчас нет соглашения по коммитам, имеет смысл договориться о формате и объяснить, как это помогает потом находить нужные изменения.


Заключение

Опция git log --grep — это удобный способ быстро находить нужные коммиты по тексту их сообщений. Вы можете:

  • искать по простым подстрокам и по регулярным выражениям;
  • настраивать чувствительность к регистру;
  • объединять несколько --grep через логику OR и AND (с --all-match);
  • комбинировать поиск по сообщению с фильтрами по автору, дате, диапазонам и файлам;
  • сочетать --grep с -S и -G, когда нужно одновременно смотреть и на текст коммитов, и на измененный код.

Эффективность git log --grep во многом зависит от качества сообщений коммитов. Чем более структурированно команда пишет сообщения, тем проще потом анализировать историю и находить нужные изменения. Если вы будете системно использовать идентификаторы задач, осмысленные префиксы и ключевые слова, --grep превратится в мощный навигационный инструмент по истории репозитория.


Частозадаваемые технические вопросы по теме и ответы

Как искать по нескольким шаблонам так, чтобы хотя бы один из них сработал, и одновременно ограничить поиск веткой

git log main --grep="BUG-" --grep="HOTFIX" --oneline
# Поиск только в ветке main
# Будут показаны коммиты, где есть либо "BUG-", либо "HOTFIX"

Как исключить из результата коммиты с определенными словами в сообщении

Git не имеет прямого negation для --grep, но можно использовать grep Unix на выводе:

git log --oneline --grep="BUG-" | grep -v "WIP"
# Сначала находим все BUG-коммиты
# Потом отбрасываем строки, содержащие "WIP"

Как искать только по заголовку сообщения, игнорируя тело

Прямой опции "искать только по subject" нет, но можно использовать формат вывода и внешний grep:

git log --pretty="%H %s" | grep "BREAKING"
# Ищем только в заголовках (%s)
# Потом по hash можно сделать git show <hash>

Как вывести только hash найденных коммитов для дальнейшей обработки в скриптах

git log --grep="PAY-101" --pretty="%H"
# Каждый hash на отдельной строке
# Удобно использовать в циклах shell или других скриптах

Как искать по сообщению только в определенной поддиректории проекта

git log --grep="migration" -- db/migrations
# --grep применится к сообщениям,
# но в выборку попадут только коммиты, затрагивавшие db/migrations
Стрелочка влевоКраткая история репозитория в Git с помощью git log --onelineГрафический просмотр истории в Git - git log --graphСтрелочка вправо

Постройте личный план изучения Git до уровня Middle — бесплатно!

Git — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Git

Открыть базу знаний

Лучшие курсы по теме

изображение курса

Основы Git

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий