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

    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.

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

    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    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.