Git добавить сообщение к коммиту

Обновлено: 02.07.2024

Несмотря на одинаковое название, команда git commit не имеет ничего общего с командой svn commit . Этот общеупотребительный термин может запутать новичков в Git, имеющих опыт работы с SVN, поэтому важно подчеркнуть разницу. Разница между git commit и svn commit — это разница между моделью централизованного приложения (SVN) и моделью распределенного приложения (Git). В SVN при выполнении коммита изменения передаются из локального клиента SVN в общий централизованный удаленный репозиторий SVN. В Git репозитории распределены, коммиты снимков состояния выполняются в локальный репозиторий, и для этого совершенно не нужно взаимодействовать с другими репозиториями Git. Позже коммиты Git можно будет передать в любой удаленный репозиторий.

Порядок действий

Не вдаваясь в подробности, Git можно рассматривать как утилиту управления временной шкалой. Коммиты — основные конструктивные элементы временной шкалы проекта Git. Их можно рассматривать как снимки состояния или контрольные точки на временной шкале проекта Git. Коммиты создаются с помощью команды git commit , которая делает снимок состояния проекта на текущий момент времени. Коммиты снимков состояния Git всегда выполняются в локальный репозиторий. В этом и заключается фундаментальное отличие от SVN, где коммит рабочей копии выполняется в центральный репозиторий. Git же, напротив, не принуждает вас взаимодействовать с центральным репозиторием до тех пор, пока вы не будете к этому готовы. Как раздел проиндексированных файлов является буфером между рабочим каталогом и историей проекта, так и локальный репозиторий разработчика является буфером между его вкладом в проект и центральным репозиторием.

Снимки состояния, а не различия

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

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

Распространенные опции

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

Выполнение коммита состояния со всеми изменениями в рабочем каталоге. Эта команда включает только изменения отслеживаемых файлов (тех, которые были в какой-то момент добавлены в историю с помощью команды git add ).

Быстрая команда, которая создает коммит с указанным комментарием. По умолчанию команда git commit открывает локально настроенный текстовый редактор с предложением ввести комментарий к коммиту. При передаче параметра -m текстовый редактор не открывается, а используется подставленный комментарий.

Команда для опытных пользователей с параметрами -a и -m . Эта комбинация параметров создает коммит всех проиндексированных изменений и добавляет к коммиту подставленный комментарий.

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

Примеры

Сохранение изменений с помощью команды commit

В следующем примере предполагается, что вы изменили содержимое файла hello.py в текущей ветке и готовы сделать коммит в историю проекта. Прежде всего, необходимо проиндексировать файл с помощью команды git add , после чего можно будет сделать коммит проиндексированного снимка состояния.

Эта команда добавит файл hello.py в раздел проиндексированных файлов Git. Проверить результат выполнения команды можно с помощью git status .

Эта команда откроет текстовый редактор (настраиваемый через git config ) для ввода комментария к коммиту и покажет список файлов, которые будут зафиксированы в этом коммите:

Особых требований для комментариев к коммиту в Git нет, но обычно первая строка содержит описания коммита длиной до 50 символов, затем следует пустая строка и детальное пояснение того, что было изменено. Пример:

Обновление коммита (параметр amend)

Продолжим работу с файлом hello.py из приведенного выше примера. Давайте внесем в файл hello.py новые изменения и запустим следующие команды:

Снова откроется настроенный текстовый редактор. Но на этот раз он будет содержать комментарий к коммиту, который мы уже вводили ранее. Это указывает на то, что мы не создаем новый коммит, а редактируем последний.

Резюме

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


На протяжении многих лет разработки ПО, будучи участником многих команд, работая с разными хорошими и опытными людьми, я часто наблюдал (да и чего греха таить, до определенного момента — создавал) одну и ту же проблему — тотальный бардак в репозитории. Каждый писал комментарии к коммитам в своем стиле (и хорошо, если постоянно в одном); половина комментариев была бесполезна (из разряда "это мост"), половина оставшейся половины — едва понятна.

И вот в один прекрасный момент я увидел данную статью, до перевода которой у меня наконец дошли руки. Всего 7 простых и коротких правил, и — о чудо — смотреть на историю коммитов стало не только полезно, но и приятно. Ничего революционного, все довольно очевидно, но сформулировано и резюмировано просто отлично.

Хочу заметить, что это статья 2014 года. Какие-то не сильно релевантные вещи, упоминаемые автором, могли потерять актуальность, но суть статьи — ничуть.

Введение: чем важны хорошие комментарии


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

Какой вариант вы бы предпочли?

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

И хотя история коммитов многих репозиториев выглядит подобно первому варианту, есть исключения. Отличные примеры — ядро Linux и сам Git. Посмотрите также на Spring Boot или любой другой репозиторий, которым занимается Tim Pope.

Участники этих проектов знают, что хорошо написанный комментарий к коммиту — это лучший способ рассказать о контексте сделанных изменений другим разработчикам (а также самим себе — в будущем). Различия в ревизиях показывают, что изменилось, но только комментарий может внятно объяснить — почему. Peter Hutterer хорошо сказал об этом:

Восстановление обстоятельств написания кода — расточительная трата времени. Мы не можем полностью ее избежать, поэтому наши усилия должны быть сосредоточены на минимизации этих затрат. Именно для этого и нужны комментарии к коммитам. Следовательно, они показывают, хорошо ли программист работает в команде.

Если вы не особо задумывались о том, каким должен быть первоклассный комментарий коммита — вероятно, вы не слишком часто использовали git log и похожие инструменты. Тут замкнутый круг: так как история коммитов неструктурированная и разнородная, ей не пользуются и не уделяют внимания. А из-за того, что ей не пользуются и не уделяют внимания, она остается неструктурированной и разнородной.

Но хорошо оформленная история репозитория — вещь прекрасная и полезная. Оживают команды git blame, revert, rebase, log, shortlog и прочие. Появляется смысл просматривать чужие коммиты и пулл-реквесты, и, внезапно, при этом теперь не требуется помощь их авторов. Разобраться, почему что-то случилось [в коде] месяцы или годы назад становится не только возможно, но и удобно.

Долгосрочный успех проекта зависит (помимо всего прочего) от того, насколько его удобно поддерживать, а история коммитов — один из самых мощных инструментов мейнтенера. Стоит потратить время на то, чтобы научиться сохранять в ней порядок. Сначала это может причинять некоторые неудобства, но потом войдет в привычку и, в конце концов, станет источником гордости и продуктивной работы всех участников.

Эта статья затрагивает лишь самую базовую составляющую ведения добротной истории, а именно — как следует писать комментарий к отдельному коммиту. Есть и другие важные вещи, например, объединение коммитов, которые здесь не рассматриваются.

В большинстве языков программирования есть хорошо описанные общепринятые соглашения, формирующие характерный стиль [написания кода], как то — имена переменных, правила форматирования и так далее. Конечно, есть разные версии таких соглашений, но большинство разработчиков придерживаются мнения, что выбрать один вариант и следовать ему — гораздо лучше, чем неразбериха, когда каждый пишет в своем стиле.

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

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

Содержимое. Какая именно информация должна (если вообще должна) содержаться в теле комментария? А чего там не должно быть?

Метаданные. Как следует ссылаться на ID задач, номера пулл-реквестов и т.д.?

К счастью, уже существуют соглашения о написании содержательного комментария. На самом деле, они частично вытекают из того, как работают некоторые команды Git. Вам не нужно изобретать велосипед. Просто следуйте семи правилам ниже — и будете на шаг ближе к истории коммитов, достойной профессионала.

Семь правил классного комментария к коммиту

1. Отделяйте заголовок от тела пустой строкой

Хотя это не обязательно, но хорошей идеей будет начинать комментарий к коммиту с одной короткой (менее 50 символов) строки, обобщающей сделанные изменения, затем пустая строка и затем более подробное описание. Текст до первой пустой строки в комментарии считается заголовком коммита и используется в разных командах Git. Например, Git-format-patch(1) превращает коммит в email; команда использует заголовок коммита для темы письма и остальной текст — для тела письма.

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

Сказанного достаточно; если пользователь захочет узнать, что именно за опечатка была исправлена, он может просто посмотреть на сами изменения, используя git show или git diff, или git log -p.

Если вы коммитите что-то в этом роде с помощью командной строки, удобно будет использовать опцию -m для git commit:


Однако, когда коммит заслуживает некоторых объяснений и описания ситуации, вам нужно записать их в тело комментария. Например:

Комментарии, у которых есть тело, не так удобно писать с помощью опции -m. Будет лучше использовать для этого текстовый редактор. Если вы еще не настроили редактор для использования с Git, прочтите этот раздел книги Pro Git.

В любом случае, разделение заголовка и тела комментария окупится при просмотре лога. Вот полная запись о коммите:


Или git shortlog, которая группирует коммиты по автору, опять же, для краткости показывает только заголовок:


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

2. Ограничивайте заголовок 50 символами


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

Подсказка: если вам тяжело резюмировать итоги работы, возможно, в одном коммите содержится слишком много изменений. Стремитесь делать атомарные коммиты (это тема для отдельного поста).


Интерфейс GitHub’а поностью поддерживает эти соглашения. Он предупредит вас, если вы выйдете за пределы лимита в 50 символов:


И обрежет все заголовки длиннее 72 символов, подставив троеточие:

Так что стремитесь к 50 символам, но учтите, что 72 — это строгое ограничение.

3. Пишите заголовок с заглавной буквы

Тут все просто. Начинайте все заголовки с заглавной буквы.

  • Accelerate to 88 miles per hour
  • accelerate to 88 miles per hour

4. Не ставьте точку в конце заголовка

В ней нет никакой необходимости. Кроме того, каждый символ на счету, когда мы пытаемся уложиться в 50.

5. Используйте повелительное наклонение в заголовке

Повелительное наклонение буквально означает: форма глагола, выражающая волеизъявления (приказ, просьбу или совет). Несколько примеров:

  • Clean your room (приберись в комнате)
  • Close the door (закрой дверь)
  • Take out the trash (вынеси мусор)
  • Refactor subsystem X for readability
  • Update getting started documentation
  • Remove deprecated methods
  • Release version 1.0.0
  • Fixed bug with Y
  • Changing behavior of X
  • More fixes for broken stuff
  • Sweet new API methods

Правильно составленный заголовок коммита должен завершать следующее предложение:

  • If applied, this commit will refactor subsystem X for readability
  • If applied, this commit will update getting started documentation
  • If applied, this commit will remove deprecated methods
  • If applied, this commit will release version 1.0.0

Убедитесь, что глаголы в других, не повелительных, наклонениях здесь не сработают:

  • If applied, this commit will fixed bug with Y
  • If applied, this commit will changing behavior of X
  • If applied, this commit will more fixes for broken stuff
  • If applied, this commit will sweet new API methods

Помните: использование повелительного наклонения важно только в заголовке коммита. В теле коммита это необязательно.

6. Переходите на следующую строку в теле на 72 символах

Сам Git не расставляет переносы строк автоматически. Редактируя тело комментария, вы должны помнить о правой границе и ставить переносы строк вручную.

Рекомендуется переходить на следующую строку на 72 символах, чтобы Git мог свободно расставлять отступы и всё еще влезать в сумме в 80 символов.

Посмотрите на изменения в коде и подумайте, сколько времени автор сэкономил настоящим и будущим участникам проекта, описав в комментарии контекст проделанной работы. Иначе он, вероятно, был бы утерян навсегда.

В большинстве случаев вы можете опустить подробности того, как именно были внесены изменения. Обычно, код говорит сам за себя в этом смысле (а если он настолько сложен, что требуются пояснения, то для этого есть комментарии в нем самом).

Сосредоточьтесь в первую очередь на пояснении причин, по которым были внесены изменения — опишите ситуацию до внесения изменения (и что было с ней не так), ситуацию после и то, почему вы выбрали именно такой способ решения задачи.

Может быть, в будущем вы поблагодарите сами себя за это!

Подсказки

Полюбите командную строку. Забудьте про IDE.

Есть множество причин — по количеству команд Git — использовать командную строку по максимуму. Git — безумно мощный инструмент; IDE — тоже, но каждая по-своему. Я ежедневно пользуюсь IntelliJ IDEA, часто имел дело и с другими (например, Eclipse), но никогда не видел, чтобы интеграция Git в IDE могла сравниться по простоте и возможностям с командной строкой (как только вы с ней разберетесь).

Определенные возможности IDE по контролю версий просто неоценимы, например автоматическое выполнение git rm, когда вы удаляете файл, или других нужных git-штук, когда вы его переименовываете. Но все гораздо хуже, когда вы пытаетесь с помощью IDE сделать коммит, слияние, перебазирование (rebase) или сложный анализ истории коммитов.

Когда требуется раскрыть полный потенциал Git, командной строке нет равных.
Помните, что используете ли вы Bash, Zsh или Powershell — существуют скрипты автодополнения команд, избавляющие вас от болезненной необходимости запоминать все подкоманды и опции.

Прочтите книгу Pro Git


Великолепная книга Pro Git (также на русском языке — прим. пер) есть в свободном доступе. Воспользуйтесь этим!

В предыдущих статьях мы рассказывали, что такое GitHub, как его настроить и как опубликовать свой проект. Но это лишь малая часть его инструментов. Одним из ключевых моментов для GitHub является работа с ветками — разбираемся с ними в этой статье.

Ветка (branch) — это история коммитов. Давайте сначала разберемся, что это такое.

Коммит (commit) — это информация об измененных файлах. Коммит состоит из автора коммита, измененных файлов, HEAD и времени. Для примеров мы будем использовать репозиторий и сделаем первый коммит, который отправим на сервер. Он нужен для того, чтобы разграничивать задачки. Так будет понятно, какой код в истории относится к той или иной задаче, чтобы потом мы могли быстро понять суть.

Например, у нас задача — сделать блок формы. Для этого мы сделаем нужные изменения в файле index.html & style.css, и даже через месяц сможем при помощи истории изменений просмотреть измененные куски кода именно для этого блока.

При помощи команды git log в консоли мы можем отслеживать историю коммитов в ветке.


На самом GitHub мы можем увидеть последний коммит в файле и последний коммит в ветке. Всю историю мы можем просмотреть, кликнув по кнопке n commits, где n — количество запущенных на сервер коммитов. У нас в ветке пока что один коммит, поэтому на ссылке надпись 1 commit.


Сама история будет выглядеть как список коммитов без подробностей об изменённых файлах. Здесь давайте подробнее остановимся на том, что такое HEAD коммита. Это специальный указатель, при помощи которого вы можете гибко управлять коммитами — например, склеивать или сбрасывать до нужного момента.



Теперь подробнее разберем, как создавать коммит. Для начала нам нужно будет поменять файлы или добавить новые, чтобы было что коммитить, так как коммит — это история изменений. Как правило, в коммит включают изменения по одной задаче.

В нашем примере мы изменим содержание страницы index.html и добавим стили в style.css.


Изменения, не включенные в коммит, мы можем просмотреть при помощи команды git status.


Чтобы добавить файлы в коммит, мы будем использовать git add. Здесь мы можем указать нужные нам файлы для коммита, например, index.html. Если после этого мы сделаем git status, то эти файлики подсветятся зелёным — это означает, что мы можем добавить их к коммиту.


Но не всегда удобно вручную вбивать все изменённые файлы. В GitHub мы можем воспользоваться командой git add . — точка означает, что в коммит добавятся все изменённые файлы.



Если мы запушим наш результат на GitHub, то увидим наш коммит.




После того, как мы поменяли наш коммит локально, запушим его на сервер при помощи ключа force. Обычный push не сработает, так как у нас уже есть коммит на сервере — здесь будьте аккуратны, ведь вы меняете историю не только локально, но и удалённо.


Теперь поговорим про ветки (branch). Ветка — это история изменений. Сейчас у в репозитории одна ветка main, в которой хранится стабильная версия. Как правило, новые задачи делаются в новых ветках, а потом вливаются в main после ревью кода.

Посмотрим, как выглядит наша ветка с двумя коммитами в графике.


Представим, что у нас есть задача — сделать форму на главной странице. Для этого создадим новую ветку git checkout -b form-index (ключ -b означает, что мы создаем новую ветку).

Ветки можно просматривать при помощи команды git branch.


История наших коммитов пока одинаковая — что у main, что у form-index. git checkout main без ключа -b означает, что мы переключаемся на уже существующую ветку.

Пробежимся git log и сравним наши ветки.


Тем не менее, если мы зайдем на GitHub, то обнаружим, что у нас там только одна ветка — main. Так происходит, потому что ветка form-index существует пока только на нашем компьютере, то есть локально.


Чтобы наша новая ветка появилась на сервере, нам нужно запушить наши изменения.



Если посмотрим на историю коммитов в form, то увидим, что она отличается от main на один коммит.


Мы можем создавать новые ветки не только из main, но и из других веток — так делают редко. Самое главное здесь понять, что если мы создали новую ветку из другой ветки, то мы наследуем историю коммитов ветки, из которой создали ветвление, но только в момент создания.

Давайте создадим ветку form-index-fix и посмотрим на историю коммитов в ней.


Теперь поэкспериментируем и посмотрим, что будет, если мы внесём изменение в ветку и забудем их закоммитить: обычный механизм через checkout не сработает, консоль попросит закоммитить изменения.


Если ветка потеряла свою актуальность, мы можем её удалить локально при помощи команды git branch -D название ветки. Здесь важно отметить, что вы не можете удалить ветку, если вы сейчас в ней — обязательно нужно переключить её.


Если ветку нужно удалить на сервере, то сделать это можно при помощи интерфейса GitHub — нет рекомендаций, когда нужно удалять удалённые ветки.



Команды для консоли


В предыдущих статьях мы рассказывали, что такое GitHub, как его настроить и как опубликовать свой проект. Но это лишь малая часть его инструментов. Одним из ключевых моментов для GitHub является работа с ветками — разбираемся с ними в этой статье.

Ветка (branch) — это история коммитов. Давайте сначала разберемся, что это такое.

Коммит (commit) — это информация об измененных файлах. Коммит состоит из автора коммита, измененных файлов, HEAD и времени. Для примеров мы будем использовать репозиторий и сделаем первый коммит, который отправим на сервер. Он нужен для того, чтобы разграничивать задачки. Так будет понятно, какой код в истории относится к той или иной задаче, чтобы потом мы могли быстро понять суть.

Например, у нас задача — сделать блок формы. Для этого мы сделаем нужные изменения в файле index.html & style.css, и даже через месяц сможем при помощи истории изменений просмотреть измененные куски кода именно для этого блока.

При помощи команды git log в консоли мы можем отслеживать историю коммитов в ветке.


На самом GitHub мы можем увидеть последний коммит в файле и последний коммит в ветке. Всю историю мы можем просмотреть, кликнув по кнопке n commits, где n — количество запущенных на сервер коммитов. У нас в ветке пока что один коммит, поэтому на ссылке надпись 1 commit.


Сама история будет выглядеть как список коммитов без подробностей об изменённых файлах. Здесь давайте подробнее остановимся на том, что такое HEAD коммита. Это специальный указатель, при помощи которого вы можете гибко управлять коммитами — например, склеивать или сбрасывать до нужного момента.



Теперь подробнее разберем, как создавать коммит. Для начала нам нужно будет поменять файлы или добавить новые, чтобы было что коммитить, так как коммит — это история изменений. Как правило, в коммит включают изменения по одной задаче.

В нашем примере мы изменим содержание страницы index.html и добавим стили в style.css.


Изменения, не включенные в коммит, мы можем просмотреть при помощи команды git status.


Чтобы добавить файлы в коммит, мы будем использовать git add. Здесь мы можем указать нужные нам файлы для коммита, например, index.html. Если после этого мы сделаем git status, то эти файлики подсветятся зелёным — это означает, что мы можем добавить их к коммиту.


Но не всегда удобно вручную вбивать все изменённые файлы. В GitHub мы можем воспользоваться командой git add . — точка означает, что в коммит добавятся все изменённые файлы.



Если мы запушим наш результат на GitHub, то увидим наш коммит.




После того, как мы поменяли наш коммит локально, запушим его на сервер при помощи ключа force. Обычный push не сработает, так как у нас уже есть коммит на сервере — здесь будьте аккуратны, ведь вы меняете историю не только локально, но и удалённо.


Теперь поговорим про ветки (branch). Ветка — это история изменений. Сейчас у в репозитории одна ветка main, в которой хранится стабильная версия. Как правило, новые задачи делаются в новых ветках, а потом вливаются в main после ревью кода.

Посмотрим, как выглядит наша ветка с двумя коммитами в графике.


Представим, что у нас есть задача — сделать форму на главной странице. Для этого создадим новую ветку git checkout -b form-index (ключ -b означает, что мы создаем новую ветку).

Ветки можно просматривать при помощи команды git branch.


История наших коммитов пока одинаковая — что у main, что у form-index. git checkout main без ключа -b означает, что мы переключаемся на уже существующую ветку.

Пробежимся git log и сравним наши ветки.


Тем не менее, если мы зайдем на GitHub, то обнаружим, что у нас там только одна ветка — main. Так происходит, потому что ветка form-index существует пока только на нашем компьютере, то есть локально.


Чтобы наша новая ветка появилась на сервере, нам нужно запушить наши изменения.



Если посмотрим на историю коммитов в form, то увидим, что она отличается от main на один коммит.


Мы можем создавать новые ветки не только из main, но и из других веток — так делают редко. Самое главное здесь понять, что если мы создали новую ветку из другой ветки, то мы наследуем историю коммитов ветки, из которой создали ветвление, но только в момент создания.

Давайте создадим ветку form-index-fix и посмотрим на историю коммитов в ней.


Теперь поэкспериментируем и посмотрим, что будет, если мы внесём изменение в ветку и забудем их закоммитить: обычный механизм через checkout не сработает, консоль попросит закоммитить изменения.


Если ветка потеряла свою актуальность, мы можем её удалить локально при помощи команды git branch -D название ветки. Здесь важно отметить, что вы не можете удалить ветку, если вы сейчас в ней — обязательно нужно переключить её.


Если ветку нужно удалить на сервере, то сделать это можно при помощи интерфейса GitHub — нет рекомендаций, когда нужно удалять удалённые ветки.

Как правильно составлять описания коммитов и почему это важно главное изображение

Заглянув в историю изменений (коммитов) какого-то рандомного Git-репозитория, вы наверняка заметите, что описания коммитов (commit messages) написаны в той или иной степени беспорядочно. Например, посмотрите на описания коммитов, которые я написал, когда начинал контрибьютить в Spring:

Выглядит не очень привлекательно. Теперь посмотрите на описания более поздних коммитов в том же репозитории.

Какие из этих описаний вы прочитаете охотнее? Старые отличаются по форме и по длине, а новые более лаконичные и однообразные. Старые как будто написаны хаотично и без системы, а новые явно писались осознанно и по упорядоченным правилам.

Как я уже говорил, примеры беспорядочных описаний можно найти в историях изменений разных репозиториев. Но есть приятные исключения, например, репозитории ядра Linux и самого Git.

Контрибьюторы этих репозиториев понимают, что правильно оформленные описания — лучший способ передать контекст коммита другим контрибьюторам, а также будущему себе. Диф помогает понять, что именно меняет коммит. Но только описания коммитов помогут понять, зачем это меняется. Важность этого момента хорошо объясняет разработчик Петер Хуттерер (Peter Hutterer) в своём посте. Вот ключевая цитата из него:

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

Если вы не задумывались, зачем нужны правильные описания коммитов, то наверняка вы не очень часто пользовались командой git log . Фактически, это порочный круг: из-за беспорядка в истории коммитов разработчики не хотят заглядывать в неё или заботиться о корректности собственных описаний коммитов. А история остаётся беспорядочной и неудобной, потому что разработчики не пользуются ей и не заботятся о корректности описаний коммитов.

Но правильно оформленная история коммитов — полезная и удобная вещь. Здесь вам пригодятся комманды git blame , revert , rebase , log , shortlog и так далее. С правильно оформленной историей изменений просмотр коммитов других разработчиков приобретает смысл. Кстати, при правильном оформлении истории изменений разобраться в ней можно самостоятельно, не привлекая к этой задаче авторов других коммитов. Вы получаете возможность понять, почему были внесены те или иные изменения в код несколько месяцев или лет назад.

В долгосрочной перспективе успех проекта зависит от того, насколько просто его поддерживать. У мейнтейнеров не так много инструментов, обеспечивающих простоту поддержки, которые могут сравниться по эффективности с правильно оформленной историей изменений. Поэтому стоит потратить время и научиться правильно её оформлять. Сначала необходимость правильно оформлять коммиты может показаться неудобством или лишней тратой времени. Но в конце концов эти усилия трансформируются в рост продуктивности команды и даже в повод для гордости.

Эта статья о том, как правильно составлять описания коммитов. Это простой способ сделать историю изменений репозитория читабельной и информативной.

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

Команде разработчиков также стоит придерживаться соглашений при работе с репозиториями в целом и формировании истории изменений в частности. Соглашение должно касаться как минимум трёх базовых вещей:

Стиль

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

Контент

Что нужно писать в описании коммита? Чего в нём быть не должно?

Метаданные

Как нужно отмечать ID issue, номера пулреквестов и так далее?

К счастью, есть общепринятые соглашения по поводу того, какими должны быть описания коммитов. Некоторые из них частично связаны с тем, как работают те или иные команды Git. То есть вам не придётся придумывать что-то самостоятельно. Придерживайтесь описанных ниже семи правил, и вы будете коммитить как профессионал.

Семь правил хорошего описания коммита

Правило 1: оставляйте пустую строку между заголовком и описанием

Отрывок из справочных материалов о git commit :

Хоть это и не обязательное требование, рекомендуется начинать описание коммита со строки длиной до 50 символов, которая обобщает изменения. За ней должна следовать пустая строка, а затем более подробное описание коммита. Текст до пустой строки — это заголовок описания коммита, он может использоваться в разных командах Git. Например, Git-format-patch(1) превращает коммит в электронное письмо, в теме которого используется заголовок описания, а в теле — само описание.

Во-первых, не каждый коммит должен иметь заголовок и описание. Иногда можно ограничиться одной строкой, если изменения очень простые.

В данном случае дополнительная информация не нужна. Если кому-то захочется узнать, какие именно ошибки были исправлены, это можно сделать с помощью комманд git show , git diff или git log -p .

Если вы делаете подобный коммит, удобно воспользоваться опцией -m в git commit :

А если коммит требует дополнительного объяснения, которое поможет другим разработчикам получить контекст, нужно делать подробное описание.

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

А теперь выведем только заголовок с помощью git log --oneline :

Или с помощью команды git shortlog выведем сгруппированные по авторам коммиты. Здесь снова выводится только заголовок описания:

В Git есть много других ситуаций, в которых в описании коммита важно иметь заголовок и тело. Но ни в одной ситуации это не работает, если между заголовком и телом описания нет пустой строки.

Правило 2: ограничивайте длину заголовка 50 символами

Это не жёсткое ограничение, а практически полезная рекомендация. Соблюдение этого правила гарантирует читабельность заголовка. Также она заставляет автора коммита задуматься и описать изменения максимально коротко.

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

Пользовательский интерфейс GitHub учитывает эти соглашения. Он предупреждает вас, если длина заголовка превышает 50 символов. А если заголовок превышает 72 символа, он обрезается. Поэтому старайтесь уложиться в 50 символов, а 72 символа считайте красной чертой.

Правило 3: пишите заголовок с прописной (заглавной) буквы

Это очень простое правило: всегда пишите заголовок описания с прописной буквы. Правильный пример:

Правило 4: не ставьте точку в конце заголовка описания

Это ещё одно простое правило: в конце заголовка точка не ставится. Кстати, лишние знаки пунктуации могут помешать вам уложиться в лимит длины 50 символов, о котором шла речь выше. Правильный пример:

Правило 5: используйте повелительное наклонение в заголовке

Если вы не знаете, что такое повелительное наклонение, думайте об этом так: заголовок должен быть похожим на команду или инструкцию. Вот примеры:

  • Сделай уборку
  • Закрой дверь
  • Вынеси мусор

Поэтому использование повелительного наклонения соответствует общепринятым соглашениям Git. Вот несколько примеров заголовков на английском языке:

  • Refactor subsystem X for readability
  • Update getting started documentation
  • Remove deprecated methods
  • Release version 1.0.0

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

  • Fixed bug with Y
  • Changing behavior of X

Иногда заголовки просто описывают содержание коммитов:

  • More fixes for broken stuff
  • Sweet new API methods

Обратите внимание, если в заголовке не используется повелительное наклонение, он не подходит по смыслу в качестве окончания предложения:

  • If applied, this commit will fixed bug with Y
  • If applied, this commit will changing behavior of X
  • If applied, this commit will more fixes for broken stuff
  • If applied, this commit will sweet new API methods

Обязательно использовать повелительное наклонение нужно только в заголовке. В теле описания коммита его можно не использовать.

Правило 6: ограничивайте длину строки в теле описания 72 символами

Git не переносит текст автоматически. Помните об этом и переносите строки вручную.

Рекомендуется ограничивать длину строки 72 символами. Это позволит Git оставить в тексте нужные отступы и уложиться в предельную длину строки 80 символов.

Соблюдать это правило поможет хороший текстовый редактор. Можно легко настроить Vim или другой редактор, чтобы он переносил строки, когда их длина достигает 72 символов.

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

Взгляните на изменения и заметьте, сколько времени автор коммита сэкономил другим разработчикам с помощью описания. Он раскрыл контекст изменений, который наверняка потерялся бы без хорошего описания коммита.

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

В будущем другие мейнтенеры поблагодарят вас за это, и, возможно, одним из них будете вы!

Вместо заключения: полезные советы

Полюбите командную строку, используйте её вместо IDE

Используйте командную строку — на то есть столько же причин, сколько команд в Git. Командная строка — очень мощный инструмент, как и IDE, но они хороши каждый по-своему. Когда нужно использовать Git на полную катушку, командная строка вне конкуренции.

Помните об автодополнении, такая функция есть и в Bash, и в Zsh, и в Powershell. Автодополнение избавляет вас от необходимости запоминать полные команды.

Читайте также: