Сегодня почти все, кто работает с кодом, хранят его в системах контроля версий, а именно git. Я очень часто вижу коммиты вроде — fix bug, implement some awesome feature, да я и сам периодически грешу подобным, давайте разберёмся, почему же важно писать адекватные сообщения и как стоит это делать, что бы было круто

Перевод статьи Chris Beams How to Write a Git Commit Message

Почему правильное commit сообщение решает

Если вы будете просматривать лог любого Git репозитория, вы скорее всего найдете там беспорядок в том или ином виде. Давайте для примера заглянем в лог ранних коммитов Spring автора

$ git log --oneline -5 --author cbeams --before "Fri Mar 26 2009"

e5f4b49 Re-adding ConfigurationPostProcessorTests after its brief removal in r814. @Ignore-ing the testCglibClassesAreLoadedJustInTimeForEnhancement() method as it turns out this was one of the culprits in the recent build breakage. The classloader hacking causes subtle downstream effects, breaking unrelated tests. The test method is still useful, but should only be run on a manual basis to ensure CGLIB is not prematurely classloaded, and should not be run as part of the automated build.
2db0f12 fixed two build-breaking issues: + reverted ClassMetadataReadingVisitor to revision 794 + eliminated ConfigurationPostProcessorTests until further investigation determines why it causes downstream tests to fail (such as the seemingly unrelated ClassPathXmlApplicationContextTests)
147709f Tweaks to package-info.java files
22b25e0 Consolidated Util and MutableAnnotationUtils classes into existing AsmUtils
7f96f57 polishing

Бам! Теперь сравним с более поздними (разница в 5 лет)

$ git log --oneline -5 --author pwebb --before "Sat Aug 30 2014"

5ba3db6 Fix failing CompositePropertySourceTests
84564a0 Rework @PropertySource early parsing logic
e142fd1 Add tests for ImportSelector meta-data
887815f Update docbook dependency and generate epub
ac8326d Polish mockito usage

Теперь вопрос, где вам более понятно, какие были внесены изменения?

  • Первые — различны по длине и форме — так происходит когда вы пишите их не особо думая, по умолчанию
  • Вторые — последовательны и коротки и ясны — такое никогда не бывает случайностью

Конечно, многие логи репозиториев выглядят как показано в первом варианте, но есть приятные исключения. Ядро линукса, собственно Git (было бы странно, если бы разработчики гита сами не писали сообщения «абы как») — превосходные примеры. Можете посмотреть репо Spring Boot или любой репо под управлением Tim Pope.

Авторы этих репозиториев прекрасно понимают, что хорошо продуманное git сообщение — лучший способ сообщить коллегам-разработчикам контекст (либо же самим себе в будущем). Diff даст вам понимание, что изменилось, но только commit сообщение даст вам понимание почему.

Peter Hutterer здорово высказался на эту тему

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

Если вы не задумывались над написанием качественных cmmit сообщений, вы не пользовались достаточно git log и подобными инструментами.

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

Внимание к истории коммитов дает возможность пользоваться прекрасными инструментами такими как: git blame, revert, rebase, log, shortlog и другими командами, которые приобретают новую жизнь. Проверка чужих коммитов и пул-реквестов приобретает новый смысл, и вдруг, может быть даже выполнена независимо! Понимание почему что-то имело место месяц или год назад становится не только возможным, но и эффективным.

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

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

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

Так же и подход к написанию commit сообщений не должен отличаться. Команде следует договориться о соглашениях написания commit сообщений.

Стоит учесть минимум три момента:

  • Стиль. Синтаксис разметки, отступы, грамматику, язык, написания, пунктуацию, использование заглавных букв. Уберите любые возможности догадок, оформите все до деталей в соглашения, максимально простым и понятным. Как результат — получите реально целостный, понятный log, который будет приятно читать, и его действительно станут читать
  • Содержимое. Какую информацию нужно указывать в теле коммита, а какую не стоит.
  • Метаинформация. Как стоит указывать номер задачи, номер pull request, и д.р.

К счастью, уже существует общепринятый стандарт о том, как же написать правильное (idiomatic) git сообщение. На самом деле, не нужно изобретать велосипед, они основаны на тех же правилах, что и сами команды. Просто следуйте этим правилам, и обещаю, ваши commit сообщения станут как у настоящего профессионала!

7 правил для написания превосходного Commit сообщения

Да, про это уже написана не одна статья, помните это

  1. Отделяй тему от тела пустой строкой
  2. Используй не больше 50 символов в теме
  3. Пиши тему с Большой буквы
  4. Не ставь точку в конце темы
  5. Используй императивную форму темы
  6. Добавляй перенос строки каждые 72 символа тела сообщения
  7. Формируя тело объясняй что и почему, а не как

Например

Summarize changes in around 50 characters or less

More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of the commit and the rest of the text as the body. The
blank line separating the summary from the body is critical (unless
you omit the body entirely); various tools like `log`, `shortlog`
and `rebase` can get confused if you run the two together.

Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain them.

Further paragraphs come after blank lines.

 - Bullet points are okay, too

 - Typically a hyphen or asterisk is used for the bullet, preceded
   by a single space, with blank lines in between, but conventions
   vary here

If you use an issue tracker, put references to them at the bottom,
like this:

Resolves: #123
See also: #456, #789

1 Отделяйте тему от тела пустой строкой

Из git commit manpage

Though not required, it’s a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git. For example, Git-format-patch(1) turns a commit into email, and it uses the title on the Subject line and the rest of the commit in the body.

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

Fix typo in introduction to user guide

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

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

$ git commit -m"Fix typo in introduction to user guide"

Однако, часто коммит требует большего объяснения, тогда пишите еще и тело

Derezz the master control program

MCP turned out to be evil and had become intent on world domination.
This commit throws Tron's disc into MCP (causing its deresolution)
and turns it back into a chess game.

Такие сообщения уже не так просто написать в терминале, используйте для этого IDE или редакторы текста

Давайте посмотрим теперь git log. Видно, что много места занимает подобный коммит

$ git log
commit 42e769bdf4894310333942ffc5a15151222a87be
Author: Kevin Flynn <kevin@flynnsarcade.com>
Date:   Fri Jan 01 00:00:00 1982 -0200

 Derezz the master control program

 MCP turned out to be evil and had become intent on world domination.
 This commit throws Tron's disc into MCP (causing its deresolution)
 and turns it back into a chess game.

Воспользуемся для этого git log --oneline

$ git log --oneline
42e769 Derezz the master control program

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

$ git shortlog
Kevin Flynn (1):
      Derezz the master control program

Alan Bradley (1):
      Introduce security program "Tron"

Ed Dillinger (3):
      Rename chess program to "MCP"
      Modify chess program
      Upgrade chess program

Walter Gibbs (1):
      Introduce protoype chess program

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

2 Отделяй тему от тела пустой строкой

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

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

UI GitHub классно помогает соблюдать это правило и дает советы

gh1

А так же обрезает все, что больше 72 символов

gh2

Итого: 50 — рекомендация, 72 — жесткий лимит.

3 Пиши тему с Большой буквы

Тут все просто, все предложения стоит начинать с большой буквы: Accelerate to 88 miles per hour

А вот так не стоит: accelerate to 88 miles per hour

4 Не ставь точку в конце темы

Не стоит тратить драгоценный символ на то, что бы соблюсти правила пунктуации

Используйте: Open the pod bay doors

А так не стоит: Open the pod bay doors.

5 Используйте императивную форму темы

Иными словами императивная форма — «сказано или написано так, будто вы даете команду или инструкцию»

  • Убери свою комнату
  • Закрой дверь
  • Вынеси мусор

Взгляните на 7 правил, именно в такой форме все они и написаны ;)

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

Давайте посмотрим, как сам git формирует системные сообщения, например git merge:

Merge branch 'myfeature'

Или же git revert:

Revert "Add the thing with the stuff"

This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.

Так что отбросив лишний стыд и сомнения, давайте покомандуем :) Примеры таких сообщений

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 your subject line here
Если применить этот коммит ваша тема коммита

Посмотрите примеры выше и попробуйте сами подставить их в эту формулу

Это правило важно соблюдать в формулировании темы, когда вы составляете тело, можете делать это в любой комфортной для вас форме

6 Добавляй перенос строки каждые 72 символа тела сообщения

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

72 — это рекомендация, что бы хватило место для отступов и форматирования, когда git выводит информацию в терминал (помните, там обычно ширина в 80 символов)

Совет: Используйте IDE или продвинутые редакторы текста, которые помогут вам соблюсти эти правила. IDEA, например, прекрасно справляется с этой задачей

7 Формируя тело объясняй что и почему, а не как

Смотрите, коммит из Bitcoin Core, шикарно демонстрирующий это правило

commit eb0b56b19017ab5c16c745e6da39c53126924ed6
Author: Pieter Wuille <pieter.wuille@gmail.com>
Date:   Fri Aug 1 22:57:55 2014 +0200

   Simplify serialize.h's exception handling

   Remove the 'state' and 'exceptmask' from serialize.h's stream
   implementations, as well as related methods.

   As exceptmask always included 'failbit', and setstate was always
   called with bits = failbit, all it did was immediately raise an
   exception. Get rid of those variables, and replace the setstate
   with direct exception throwing (which also removes some dead
   code).

   As a result, good() is never reached after a failure (there are
   only 2 calls, one of which is in tests), and can just be replaced
   by !eof().

   fail(), clear(n) and exceptions() are just never called. Delete
   them.

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

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

Поверьте, разработчики из будущего будут вам благодарны, возможно им окажитесь вы сами!

Полюбите  terminal. IDE не всегда хороши

Почему? Потому что максимум возможностей git вы сможете использовать лишь в командной строке. Во многих IDE есть поддержка git, но все же, иногда в командной строке некоторые действия можно сделать быстрей и проще, если уметь ей пользоваться. И конечно же некоторые функции сильно проще делать через IDE, например, merge, перемещение файлов, например, но как только нужно сделать rebase, куда проще отрыть консоль и сделать нужные действия.

Используйте комбинацию инструментов, пользуйтесь git на полную, пишите качественные сообщения как настоящий профессионал!