Стиль именования коммитов

    the Octobi Wan Catnobi

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

    Зачем это вообще нужно? Чтобы экономить время и нервы, не больше и не меньше. Это мы еще обсудим чуть позже, а пока рассмотрим как же вообще именуются коммиты.

    Общий стиль


    Если пройтись по тем же коммитам с GitHub, то можно увидеть довольно обширное количество вариантов написания коммитов. Основные рекомендации по написанию можно выделить такие:

    Что сделать + для какой сущности + подробности (необязательно)

    Старайтесь найти единый стиль для коммитов и придерживаться его. Для себя я нашел удобным такой стиль, когда я сначала указываю что я делаю. Например, add. После этого я указываю что-то, над чем я произвожу действие. Например, ui-bootstrap.js dependency. В большинстве случаев такой записи более чем достаточно. Если есть еще какая-то пояснительная надпись, то ее лучше вынести в отдельную большую запись, о чем мы еще поговорим. Если запись маленькая, но очень нужная, то можно дописать её прямо к коммиту. Но лучше еще раз задуматься, действительно ли нужна эта надпись, или она будет привлекать ненужное внимание.

    Бывает так:
    dependency for managing ui-bootstrap.js components was added here on 18.06.2013 by olegafx
    

    Но лучше:
    add ui-bootstrap.js dependency
    

    Большие сообщения в коммите

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

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

    replace twitter-bootstrap.css with pure.css
    
    Made UI much cleaner.
    
    BREAKING CHANGE. You need to use new class-names for grid-related elements.
    

    Пишем сообщение с маленькой буквы

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

    Бывает так:
    Add ui-bootstrap.js dependency
    ADD ui-bootstrap.js dependency
    

    Но лучше:
    add ui-bootstrap.js dependency
    

    НЕ используем прошедшее время

    Чем проще, тем лучше. Прошедшее время слишком усложняет чтение сообщений. Предстаьте, что вы обращаетесь к Git: «Git, добавь», «Git, удали» и т.д.

    Бывает так:
    added ui-bootstrap.js dependency
    

    Но лучше:
    add ui-bootstrap.js dependency
    

    Убираем лишние знаки препинания

    Например, зачем вам точка в конце сообщения? Итак понятно, что оно закончено. То же самое относится к точке с запятой.

    Бывает так:
    add ui-bootstrap.js dependency;
    

    Но лучше:
    add ui-bootstrap.js dependency
    

    Русский язык


    Нет ничего постыдного в том, чтобы использовать русский язык в коммитах. Но делать это нужно только в том случае, если вы на 1000% уверены, что данный код будет интересен только русскоязычным людям. Например, у вас есть скрипт для VK, который указывает на карте всех фанатов Стаса Михайлова. Очевидно, что это будет мало кому интересно среди зарубежных граждан. Да и для россиян тоже, если честно.

    Причесываем коммиты перед отправкой


    Все коммиты в локальном репозитории можно именовать как угодно. Если вам проще запомнить, что «temp commit 1» — это первая рабочая версия какой-то функциональности, а «temp commit 2» — это ее исправленная и отрефакторенная версия, то пожалуйста, никто особо вас ругать не будет. Но. Огроменное НО. Перед отправкой приведите, пожалуйста, свои коммиты в самый лучший вид. Для большинства случаев подойдет замечательная команда:

    git rebase -i
    

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

    Находим свой любимый стиль


    Я нашел такой в проекте AngularJS. У них есть даже отдельный документ, посвященный оформлению коммитов. Все моменты, о которых я рассказал выше, есть в этом документе. И это прекрасно. Потому что мне приходилось искать эти моменты самому из разных источников, своего опыта, а здесь все лежит уже в одном месте и написано хорошим простым языком. Кратко рассмотрим основные моменты.

    Указываем тип коммита

    Есть несколько заранее определенных типов:
    • feature — используется при добавлении новой функциональности уровня приложения
    • fix — если исправили какую-то серьезную багу
    • docs — всё, что касается документации
    • style — исправляем опечатки, исправляем форматирование
    • refactor — рефакторинг кода приложения
    • test — всё, что связано с тестированием
    • chore — обычное обслуживание кода

    Не всегда эти типы можно легко различить при написании приложения (например, refactor и chore), поэтому можно придумать свои.

    Указываем область действия (scope)

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

    Например, может быть область видимости модуля:
    refactor(audio-controls) use common library for all controls
    

    Или область видимости файла:
    chore(Gruntfile.js) add watch task
    

    Для чего всё это

    Как я уже говорил в самом начале статьи, для сохранения времени и нервов! Путём упрощения следующих операций:
    • Автоматическая генерация списка изменений (CHANGELOG.md и подобные). Даже если он не сформируется полностью, то будет хотя бы какя-то отправная точка для внесения небольших поправок.
    • Игнорирование неподходящих коммитов при поиске места, где все сломалось (например, с помощью git bisect).Коммиты, улучшающие документацию, тесты, стиль кода и т.д. могут сразу быть пропущены. Если у вас сломался модуль audio-controls, то вы будете смотреть только те сообщения, где в scope указан данный модуль.
    • Просто более насыщенная и понятная история развития проекта.

    Заключение


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

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

    Приятного кодинга!

    Only registered users can participate in poll. Log in, please.

    Как вы оформляете коммиты?

    • 27.1%Произвольный порядок слов374
    • 40.5%С большой буквы558
    • 40.5%В прошедшем времени559
    • 35.3%По настроению487
    • 38.1%Качественно525

    Similar posts

    Ads

    Comments 51

      +3
      > старайтесь использовать хороший стиль именования коммитов в своих проектах
      В командных проектах есть договорённость (номер тикета, описание, зависимости)
      А в личных точно по настроению… бывают и не приличные :))
        0
        У меня на этот случай есть небольшой хук, который добавляет название ветки к сообщению коммита.
        0
        Спасибо. Очень вовремя. Раньше слабо задумывался о том, как оформлять сообщения к комитам.
        А сейчас кодовая база разрослась, надо наводить порядок. А тут как раз ваша статья.
          +13
          Не согласен с пунктами про большие буквы, знаки препинания и прошедшее время.

          При всей лаконичности, сообщения должны быть написаны на нормальном языке — например вот тут у вас времена намешаны, в результате если просто прочитать это сообщение, то может показаться, что вы улучшили UI, а теперь просите кого-то заменить twitter-bootstrap.css на pure.css:
          replace twitter-bootstrap.css with pure.css

          Made UI much cleaner.
            –8
            В статье по этому поводу всё написано:
            Предстаьте, что вы обращаетесь к Git: «Git, добавь», «Git, удали» и т.д.


            В основном сообщении не используется прошедшее время. В пояснительной записке можно писать всё, что угодно, как угодно.
              +26
              Это бред. Мы не обращаемся к гиту, мы пишем commit message для log'а. Git не Siri.
                –7
                Никому ничего не навязываю. Мне удобнее писать так. От «Added» коммит понятнее не станет, потому что итак понятно, что он был в прошлом.
                  +12
                  Зачем же вы в статье прошедшее время использовали, и так же понятно, что она в прошлом написана. :)
                    +3
                    То есть соблюдать банальные правила английского языка — необязательно? Более того, прошу вас привести вывод
                    git log --oneline -20
                    
                    и прочесть потом вслух.
                      –5
                      Что именно вы не сможете прочитать в такой истории?
                        +5


                        Либо Fix for a few issues, либо Fixed a few issues. Тут надо определиться что в commit message пихать: описание коммита, или описание выполненных действий в рамках коммита.

                        В данном случае — ни то, ни то.
                          –5
                          Ну так и напишите тому человеку. Мне-то вы зачем это пишете? :)
                            +1
                            Вы привели мне пример, я на него ответил. Вы придерживаетесь того же стиля что и автор данного коммита?
                              –2
                              Я придерживаюсь стиля, описанного в статье. Во-первых, я бы указывал конкретные «issues». А во-вторых, «fix issues» — вполне нормальная конструкция.
                              Fix security issues
                                +2
                                Fix security issues to protect and secure Windows automatically

                                Вырывать из контекста нехорошо.
                                  0
                                  Вполне нормальная конструкция для указания того, что нужно исправить. Можно еще please добавить ;)
                                  Я использую настоящее время в названии тикета и прошедшее в коммите.
                    +10
                    В статье по этому поводу всё написано:
                    Я не говорю, что не заметил вашего обоснования этих советов в статье. Я говорю, что я лично с ними не согласен, и привожу свое мнение. Я не хочу представлять, что я обращаюсь к Git. Git Не будет читать эти сообщения, их будут читать другие разработчики. Соответственно, я считаю, что человеку удобнее будет и понятнее читать
                    Fixed a critical issue in module.cpp; please refer to readme.txt for more information.
                    а не
                    fix(module.cpp) critucal issue

                    Additional info in readme.txt.
                    Заметьте, я не призываю писать в commit message эссе на 10 листов. Но можно одновременно писать и кратко, и грамотно — с нормальными временами и знаками препинания.
                      0
                      Я где-то читал, что настоящее время лучше писать для того, чтобы было удобнее читать что делаеют коммиты при интерактивном ребейзе — ведь мы только собираемся пикнуть тот или иной коммит, а там прошедшее время.
                        +2
                        Это не настоящее время, а императив. Почувствуйте разницу между «fix issue» и «fixes issue».
                    +2
                    Полностью согласен с Вами по обоим пунктам. Начинаю с прописной буквы и всегда пишу в прошедшем времени.
                    +1
                    Я просто оставлю это здесь
                    tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
                    –2
                    Думаю, Вы путаете прошедшее время и третье лицо.
                      0
                      может пассивный залог?

                      small bug (is) fixed — маленький баг поправлен

                      п.с. кстати, я именно так и пишу и считаю, что разговаривать с гитом — тупо
                      +2
                      А что делать, если надо коммитнуть кучу файлов?
                      Например, я добавил или изменил функциональность в некоторых базовых классах — хорошо бы для каждого класса описать в комментарии к коммиту, что изменилось, чтобы когда-нибудь потом глядя историю одного файла видеть, что в нём менялось с каждым коммитом, и какую ревизию открывать, если вдруг надо вернуть старую функциональность. Но одновременно весь коммит добавляет или изменяет функциональность всего приложения — это тоже неплохо бы описать.
                      Писать длинный-длинный комментарий ко всему коммиту? Или коммитить сперва базовые классы отдельно, с комментированием изменений?
                        –4
                        У хорошего коммита, как и у хорошего комментария, должна быть одна зона ответственности. Если вы в одном коммите меняете разные модули, классы, то это бардак (по моему мнению). В git есть замечательные теги, которые можно применять к коммитам. И потом сравнивать уже по тегам.
                          +4
                          Один коммит — на одну логическую единицу. Не важно, в одном файле или разных.
                        +6
                        Не знаю, как другие делают, но у меня комментарий к коммиту отвечает на вопрос: что я сделал в данном коммите. Поэтому я все пишу в прошедшем времени. И использование/неиспользование заглавных букв — дело привычки. Тут уже все от принятых стандартов зависит.
                          0
                          Что вы сделали я могу в самом коммите посмотреть, комментарий должен объяснять ЗАЧЕМ вы это сделали. Очень сильно это помогает в командах, где работают в разных часовых поясах.
                            0
                            В смысле зачем? Не писать, что я реализовал фичу #X, но написать: я реализовал фичу #X, потому что она стояла у меня в задачах?
                              0
                              #X — Feature added

                              This feature helps to make things
                              easier in workflow and reduces
                              code complexity.
                                0
                                Зачем писать это в коммите, если это есть в баг-трекере?
                                  +1
                                  Два момента:

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

                                  2. Гораздо удобнее сделать git log вместо того, чтобы лезть в браузер и искать этот тикет.
                            0
                            Ну можно посмотреть на это не со стороны разработчика, а со стороны мэйнтейнера.
                            Для него коммит отвечает на вопрос: «Что произойдет, если я пульну или смержусь с ним?»

                            Хотя лично я пишу в прошедшем времени.
                              +3
                              Самое главное — это указывать issue (через #ISSUE_ID) к которому относится коммит. Очень полезно при серьезной работе на github.
                              Остальное — мелочи.
                                +2
                                Не согласен про мелочи. Так и представляю:

                                $> git log --pretty=oneline
                                
                                fd6ab367a690e2dd438e3282ea9d2c8415f2296a #54!!!
                                afd843c40a9e5df6663dbf122f673d1c2eea77bf #42, #43 and #35
                                7ad7a34bef74124100465eac02241a0484b2f4db #31, #32
                                


                                А так да, многие системы управления проектами подхватывают ссылки на коммиты, если указывать номер тикета.
                                  +2
                                  Да, кстати такое я вот тоже видел :)
                                  Но все же стараюсь писать:

                                  Working on someshit (#31)
                                  — added new blah
                                  — removed few blah
                                  — …
                                  — profit!
                                  +1
                                  Гит прекрасен тем, что позволяет полноценно работать и без интернета. Не спорю, указывать номер полезно, но чем вам поможет номер бага/тикета, когда вы не можете его прочитать? Более того, номер тикета — это несколько дополнительных кликов в браузере. Комментарий, который объясняет, для чего сделаны изменения, сохранит вам время и нервы.
                                    0
                                    Я понимаю. Но в начале статьи висит иконка github — вот я и говорит в рамках github (активно использую его для работы).
                                  +1
                                  Комментарии в настоящем времени читаются довольно странно. Коммит — это фиксация того, что мы сделали.
                                    +1
                                    А ещё можно не мудрствовать, а просто вписывать номер задачи.
                                      0
                                      Я бы к этому добавил краткое описание. Полезно, чтобы другие члены команды в общих чертах представляли что произошло без необходимости обращатсься к трекеру. Например:
                                      [SDK-513] Added compile-time check that ... supports ...
                                      [ABC-1231] Enabled progress indication
                                      [ABC-1311] Deleted unused code
                                      Теперь окинув взглядом историю можно быстро оценить что произошло за последнее время.
                                      +3
                                      Пишу имя тикета в JIRA, затем текст коммита в прошедшем времени. Мне кажется, так удобнее читать :)
                                        +1
                                        Совсем недавно GitHub обновил дизайн, сосредоточившись, как это сейчас принято, на контенте. В контексте гихаба (а им, я уверен, пользуются многие хабровчане), именование коммитов в прошедшем времени выглядит гораздо логичнее, чем в настоящем:

                                          +2
                                          Я стараюсь придерживаться следующего стиля: «Номер задания в багтрекере или затронутая область подсистемы (пространство имён): описание изменений». Пространство имён указываю либо общее для группы изменений либо пишу несколько подобных записей в одном коммите (если так вышло, что в одном коммите приходится фиксировать, например, несколько изолированных друг от друга изменений и изменение, затрагивающее файлы всех этих изолированных изменений). В целом, стараюсь фиксировать изолированные изменения по отдельности (если речь не идёт о черновой стадии работы над индивидуальным проектом). Описания стараюсь писать безотносительно времени (описывая изменение как факт).

                                          Примеры нескольких коммитов:
                                          1. ESH-419: тут либо дублирую заголовок из багтрекера либо перефразирую его в более подходящий вид (если заголовок, заданный автором задания в багтрекере не совсем точно соответствует вносимым изменениям)
                                          2. components.shop.basket: добавление поддержки товара типа «ноутбук» в корзине покупок
                                          3. components.shop: исправление ошибки взаимодействия корзины покупок и списка товаров
                                            0
                                            В паре личных проектов использовал следующую нотацию:
                                            В начале в квадратных скобках ставится модификатор действия:
                                            +: added
                                            — : deleted
                                            *: modified (любая модификация, кроме фикса, которая хорошо описывается как «изменение»)
                                            f: fixed
                                            Далее идёт объект, над которым совершалось изменение (без глагола).
                                            [+] Tests for component X.
                                            Многострочные комментарии не использовались, так как любое слишком крупное изменение разбивалось на два коммита.
                                            После объекта идёт опциональный параметр, который записывается как [/]. Это индикатор т.н. partial-коммита, который не переводит проект в целостное состояние. Обычно, такие коммиты создаются в пылу кодинга, а потом подчищаются с помощью amend / rebase на свежую голову.
                                            В конце обязательно ставится точка.
                                            Мерж-коммиты, как правило, содержали описание основных фич, которые были смержены.
                                            В целом, концепция была неплохая, но и без неё тоже неплохо работается. Тем более, если работаешь над проектом один. Описание коммита важно, но содержание важнее.
                                            Сейчас в личных проектах пользуюсь нотацией «по настроению».
                                              +2
                                              Action. short desc. issue#

                                              Fix. internal error during on-boarding. #1192
                                              Feature. add pckry everywhere. #1193 #1194
                                              Fix. too many requests to facebook during usual tasks. #1201 [WIP]
                                                0
                                                Я предпочитаю писать комментарии к коммитам в прошлом времени, но качественно.
                                                  0
                                                  action<. short desc>
                                                  <[fix/ref] issue id1: what was made for issue1>
                                                  <[fix/ref] issue idN: what was made for issueN>

                                                  short desc — до 60 символов
                                                  action — только в прошедшем времени:

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

                                                  Я не пишу это в гите. И не работаю в гите. Но мои проекты на гитхабе)

                                                  система контроля версий может поменятся — история должна быть читабельной.
                                                  багтрекер может поменятся — хорошо если с сохранением тасков.
                                                  интернета может не быть — никаких ссылок
                                                    0
                                                    Мой комментарий запоздал всего на пару лет, но всё же напишу. :) Тут много спорили о том, в прошедшем времени писать или в настоящем. Сами разработчики Git рекомендуют использовать императивный стиль:
                                                    Describe your changes in imperative mood, e.g. «make xyzzy do frotz» instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy to do frotz", as if you are giving orders to the codebase to change its behaviour.


                                                    Но каждый, конечно, решает сам. Хороший комментарий (пусть даже в будущем времени) будет лучше плохого, хоть и написанного по всем правилам.

                                                    Only users with full accounts can post comments. Log in, please.