Comments 84
По-моему, если у вас большинство комментариев типа «поправил баг» и «небольшое изменение», то у вас куда более серьёзные проблемы. Нужно начинать с них, требуя у разрабов понятного описания (возможно, с обязательной ссылкой на задачу в багтрекере), а потом уже возиться с оформлением. Или делать это одновременно, но описание должно быть приоритетней.
Спасибо за комментарий. Скриншот в начале статьи немного приукрашивает действительность, но спешка и отсутствие договоренностей действительно приводят к подобному результату. Правила и автоматизация помогают избегать подобного.
fix(products): поправить длину строки с ценой

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

МЕТА ДАННЫЕ: SECRETMRKT-578, SECRETMRKT-602

Мне кажется, что тут возникла небольшая ошибка. Коммит — не то, что должно быть сделано, а то, что уже сделано. Что нужно сделать должно быть написано в таске где-то или в требованиях. Как я понял, в этом примере такая информация находится в SECRETMRKT-578, SECRETMRKT-602. Т.е. верный вариант будет
fix(products): поправлена длина строки с ценой

Часть заголовков неправильно отображались в мобильной версии из-за ошибок
в проектировании универсальных компонентов.

МЕТАДАННЫЕ: SECRETMRKT-578, SECRETMRKT-602

И тогда автоформирование Change Log уже взлетит само собой.

UPD: Да, не дочитал. В статье об этом есть в конце. Но мне всё равно кажется это несколько странным.
В статье несколько раз упоминается про повелительное наклонение которое рекомендуется использовать самим гитом, поэтому и получается «сделать, исправить» и т.д. Сам я если честно тоже плохо воспринимаю в таком формате коммиты, как будто задача не завершена этим коммитом, а наоборот коммит породил задачу.
А мне норм: коммит — указание VCS сделать какие-то изменения в кодовой базе. Особенно хорошо, если сообщение коммита копируется из названия задачи — типа я делегирую VCS задачу, назначенную на меня, детализируя какие конкретно изменения сделать, чтобы задача была решена
Предположу, что так сделано из-за идеи в гите с переписыванием истории коммитов. В английском варианте:
If I (merge|cherry-pick|rebase|use|...) this commit it will (commit message):
If I use this commit it will «Add logout button to home page».

Это позволяет мейнтейнерам буквально по кусочкам собирать нужную цепочку из сотен коммитов и веток.

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

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

Так никто так коммит в разговоре не описывает, ни по-русски, ни по английски. Но соглашение уже как бы выбрано, так что или иму следуем, или все переделываем.
Инфинитив удобно использовать в названиях pull/merge реквестов, как отражение самих задач для разработки (сделать, добавить, исправить, ...). Они в свою очередь порождают рабочие ветки в git, а по завершении (squash & merge) сопровождаются комментарием в нужном стиле и аккуратно укладываются в master.

Правки внутри рабочих веток удобно именовать в стиле бортового журнала (т.е. как угодно), т.к. они отражают ваш путь решения задачи. Чем сложнее задача, тем путь может быть более удивительными и непредсказуемым. Здесь главное не мешать творческому процессу — чем меньше церимоний тем лучше. Во время squash все эти шаги будут удалены или переписаны.

Если вдруг покажется, что вливаемые в master изменения слишком крупные или слишком мелкие, или неочевидные, то значит херня творится на уровне постановки задач. Может в работу под видом задачи на разработку попадают сразу стори или целые эпики, или какие-то невнятные хотели. В таком случае дрючить разработчиков за именоваание комитов бесполезно.
Мы пару лет в студии писали коммиты на английском (без использования методологий). В итоге получилось так что когда пришлось читать историю одного проекта все осознали что больше половины коммитов непонятно о чем. В итоге пришли к тому что лучше для коммитов оставить только русский.

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

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


Для коммитов на русском языке просто следовать этому правилу: "Используйте повелительное наклонение", будет не благозвучно и думаю не правильно с точки зрения русского языка, тут говорится: "Use the imperative mood in the subject line" и поясняется, что заголовок должен быть продолжением фразы: "If applied, this commit will your subject line here", пример:


If applied, this commit will update getting started documentation
В случае применения этого коммита будет обновлено руководство по началу работы

Без начала предложения т.е. без глагола will в английском языке получается imperative mood:


update getting started documentation
обновить руководство по началу работы

а в русском языке, если не ошибаюсь, это инфинитив:


обновить руководство по началу работы
обновить конфигурацию commitizen
добавить хук забытый в прошло коммите

а повелительное наклонение образуется иначе:


обновите руководство по началу работы
обновите конфигурацию commitizen
добавьте хук забытый в прошло коммите

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


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

В таком случае комментарии получаю такой вид:


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

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


Мне будут очень интересны другие мнения на эту тему.

Логика есть, но вот не уверен что русский вариант правилен. «If applied, this commit will update getting started documentation» скорее переводится как «Будучи примененным этот коммит будет обновлять руководство ...» или более благозвучно без изменения грамматики основной части «При применении этот коммит будет обновлять руководство ...». То есть тот же инфинитив по сути, неопределнная форма глагола в изоляции и (простое) будущее в сочетании с будет/will

ЗЫ

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

Так обновит в итоге или нет? Несовершенный вид, как мне кажется, тут вообще не подходит.
Возможно, тогда «не будет обновлять», а «При применении этот коммит обновит, добавит, исправит, улучшит...» В принципе при чтении коммитов перед мержем/пуллом очень даже логично выглядит — какой эффект от применения коммита будет
«commit will update» — коммит обновит, и никаких пассивных залогов «будет обновлено». Адресаты плохо воспринимают пассивный залог, потому что не видят картинку. На эту тему психологи и филологи написали уже много работ, защитили достаточно диссертаций, создано множество style guide etc. Причём это не зависит от языка (если пассивный залог в языке вообще есть).
Несмотря на это, меня почему-то смущает активная позиция коммита.
Интуитивно я бы предпочёл в качестве актора видеть атора коммита. «Этим коммитом я…
*… исправил ошибку»
*… добавила фичу"
*… увеличил производительность"
*… упорядочила отступы"

Кто-то может возразить, что это обращает необоснованно много внимания на личность автора, даже пол его тут проявляется. А по мне, это даже плюс. Чьи-то коммиты нужно перепроверять 100 раз, и запашок от них идёт на версту, а чьи-то и смотреть незачем — там всё хорошо, правильно и ровно.
Как по мне, на английском языке коммиты в повелительном наклонении воспринимаются хорошо. Само собой получается так их писать.
А на русском выглядит очень странно. Да.
Погуглил — есть тулзы и на других языках (питон например), если кому не охота `npm` юзать по причинам частых проблем с безопасностью или отсутствием необходимости иметь npm.
Отличный материал, спасибо! Есть вопросы:
1. Список изменений (changelog.md) генерируете на основе истории или нет (есть мнение, что это не лучший способ), какой подход у вас к созданию и поддержке истории изменений?
2. Применяете git-flow или свой поход? Расскажите подробнее.
3. Интересно как относитесь к линейной истории это полезно или нет? Мое мнение, что линейная или частично линейная история дает массу профитов и даже применяя git-flow история может быть линейная, если приложить немного усилий, но мало кто видит в этом преимущества, давно хочу понять почему. На текущий момент гипотиреоза в том, что мало кто использует историю как инструмент анализа или может быть есть иной способ сохранить блейм или анализировать историю в незавидности от ее линейности.
Спасибо. Могу поделиться опытом нашей команды:

1. Change Log не ведем, есть Release Notes. Перед каждым Pull Request-ом разработчик заполняет в файле ReleaseNotes.md следующие пункты:
— New (Что нового? (фичи, новая функциональность));
— Improvements (Какие улучшения мы добавили в существующие фичи);
— Fixes (Список исправленных багов);
— Operations (Eslint, обновление библиотек и т.д.).

На основе этого файла формируются Release Notes каждой версии. Этот документ смотрят QA специалисты. После публикации версии содержимое файла ReleaseNotes.md обнуляется.

2. Выбрали классический git-flow (хотя сам я сторонник другого ветвления). Это правильно по многим причинам, но для меня главная — открытость к ротациям в команде. Отраслевые стандарты позволяют свести начальный инструктаж к минимуму.

3. Не задумывался линейна или не линейная история. Использую в работе удобный GitKraken, всё наглядно. За ссылки благодарю, изучу внимательно этот вопрос.
1. Перед каждым Pull Request-ом разработчик заполняет в файле ReleaseNotes.md

Это один файл на проект? Учитывая конвенцию и генерацию коммитов что мешает это файл формировать автоматически?

2. Выбрали классический git-flow (хотя сам я сторонник другого ветвления)

Другого ветвления, это какого?
Учитывая Ваш опыт применения git-flow, представите, что будет с историей, если каждый разработчик будет синхронизировать свою рабочую ветку не слиянием с develop, а через перемещение git pull --rebase origin develop?
Ай ай ай, бесплатный GitKraken запрещён для коммерческого использования
мы стараемся придерживаться строго линейной истории, но вот недавно перешли со строгого --no-ff на строгий --ff, что бы были видны мерж коммиты.

Ребейз перед мержем в мастер у нас прям обязателен, потому что лучше разрешить все конфликты до мержа, но получаются force пуши в ветки.
да. --ff выключает поведение при котором merge коммит не сделается, если его можно не делать.

Мы решили, что лучше он будет всегда.
да. --ff выключает поведение при котором merge коммит не сделается, если его можно не делать.

Я, может, чего-то не понимаю, но это поведение --no-ff


--no-ff
Create a merge commit even when the merge resolves as a fast-forward.

А --ff как раз мёрж коммиты может не создавать


--ff
When the merge resolves as a fast-forward, only update the branch pointer, without creating a merge commit.

Цитаты вот отсюда https://git-scm.com/docs/git-merge

И какой смысл? Огромное количество изменений в коммите просто убивает всю историю, никто не сможет понять что там изменилось. Практика микрокоммитов и проблемы в неймниге отпадет само собой.
Мой опыт говорит обратное, если вести историю по правилам, то как минимум можно воспользоватся git changelog, дает вполне адекватный материал, который можно обработать в ручном или полу-автоматическом режиме. Например применить агрегацию и фильтрацию на основе типов. Мы это делаем руками, надеюсь есть инструмент о котором я еще не знаю.
Я немного о другом.
Типичный случай. Нужно пофиксить сложный баг — в первую очередь иду смотреть историю гита, анотации. Если микрокомиты с тегами — то все легко, сразу видно коммит в имени которого сразу прикреплен номер таски по которому эти изменения были сделаны и почему, даже если они были сделаны 5 лет назад. А уже в таске все прописано, аналитика, какие кейсы для воспроизведения, и почему конкретно было принято такое решение.
А если это левый мердж, в котором под сотню ченджей, без тикета и тегов — то и смотреть бесполезно.
А список ченджей он никому то и не нужен, написать можно всякое
Аннотации или git blame это отдельная история в теории за его формирование отвечает правила по оформлению кода и текущие конвенции не решают этот вопрос полностью, в общем это отдельная тема.

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

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

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

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

Имхо написание хороших коммит сообщений важно не только для просмотра истории, но и для более чистого кода в репозитории. Когда я знаю что мне нужно описать коммит, я еще раз просматриваю все изменения, и порой начинаю дробить их на пару мелких коммитов, так как понимаю что сделал по факту несколько задач.
Не хватает возможность описывать смешанные типы и области для коммитов.
Области по своей природе могут смешанными при каких-то сложные и больших правках. Переход на новые библиотеки, утилиты сборки, какой-то глобальный рефакторинг и т.п.
Смешанные типы это в общем случае плохо, но для маленьких проектов практически неизбежно, т.к. строгое следование лучшим практикам может трудоёмкость в небеса и сделать такие проекты бессмысленными.
В таких случаях лучше предусмотреть возможность.
Кстати, в какой-то момент времени оказалось, что комментарии коммитов этого хорошо, но нужен внятный независимый ченжлог. Прикрутил его формирование по коммитам. А потом оказалось, что удобнее сделать наоборот — генерировать комментарии по изменение ченжлога. Нужно сказать, что некоторое время было прямо счастье. И в больших и в маленьких и даже в микро-проектах дописывает правишь текстовый ченжлог (по правилам -с разделением на фичи/баги и т.п.), потом делаешь коммит и комментарий генерируется из изменений ченж-лога. Одновременно переформатируется сам ченжлог — добавляется информации о дате коммита, номере сборки, статусе релез/дебаг и т.п. А при коммите в релиз всё это автоматически собирается (от прошлого релиза) ещё раз переформатируется, собирается в один большой список изменение, снабжается версией, генерируется комментарий в коммит. Очень удобно было! Имеешь текстовый файл с описанием основных изменений, имеешь список изменений для релизов и т.п.
Но всё держалось на мега-скрипте для баша, который со временем превысил предел сложности, развалился не несколько версий и т.п. А духу и времени всё это облагородить и переписать на каком-нибудь пайтоне не находится. В результате в новых проектах снова обычные комментарии к коммитам :(

Смешанные области просто не надо указывать вообще. Смысл указания области в том, чтобы можно было легко пропускать коммиты, которые явно не представляют интереса. Если сложно чётко описать, что затрагивает коммит, а что нет — просто не надо указывать ничего. Если коммит затрагивает пару областей — никто не запрещает указать обе через запятую: "fix(this,that): something".


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


В таких случаях лучше предусмотреть возможность.

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

Ну, почему же. Описать можно. Просто коммит может затрагивать две области.
Что значит забить на стандарт? Никто не призывает «забить». Но под стандарт пуштся парсеры и утилиты. И если в реальном мире есть какая-то ситуация, а стандарт её не предусматривает, то это хреновый стандарт и от него будут в этой ситуации отступать. Или просто будут использовать какие-то другие соглашения.
Стандарт, он не для того, чтобы разработчиков дрессировать. Он для того, чтобы можно было различные утилиты совместимым образом автоматизировать. А вопросы, что и когда можно, а что нельзя решают договорённостями в каждой конкретной команде под её конкретные потребности.
Вот, я например, не могут делать один коммит на одну область/тип. Просто потому, что нет у меня таких ресурсов под такие небольшие проекты. И это популярная ситуация. На самом деле матёрый энтерпрайз это скорее исключение, чем правило и большинство команды вынуждено идти на компромисы. По крайней мере до тей пор, пока проекты не достигнут определённой степени зрелости и/или коммерческого успеха. Значит они (и я в их числе) будут городить свои костыли. Писать несколько областей или типов через запятую, скорее всего. И все утилиты я будут пилить под это. Но это рушит совместимость, обесценивает и ограничивает стандарт. А если окажется, что что-то стандартное я допилить не могу, то я просто не будут использовать этот стандарт и будут искать что-то другое.
Меня всегда удивляет, когда разрабатывают стандарт, но не закладывают каких-то очевидных расширений в него.
Стандарт допускает следующие типы коммитов:

Это не совсем так. Стандарт (текущая версия v1.0.0-beta.2) определяет два особых типа (feat и fix) и отдельно все остальные. Для остальных приведены несколько примеров, но не более того.


Описание коммита не должно закачиваться знаками препинания.

IMHO здраво, но стандарт этого не требует, хотя примеры написаны в этом стиле.


В описание необходимо использовать повелительное наклонение (imperative mood), точно такое же, какое использует сам Git.

IMHO плохая идея, и стандарт этого даже не упоминает. Более того, многие примеры явно не в этом стиле: "feat(lang): added polish language", "fix: minor typos in code"…


Я бы не придирался, если бы Вы сказали, что описанное — это ваше внутреннее соглашение, но ведь Вы поместили все эти пункты под заголовок "Основные тезисы Conventional Commits", что явно не соответствует истине.


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

А вот это явно противоречит и духу и букве стандарта. Стандарт рекомендуется применять в момент ручного squash фиче-бранча. Нигде не рекомендуется использовать его для каждого коммита внутри фиче-бранча (и это очень здраво). Не уверен, возможно ли ограничить упомянутые утилиты исключительно этими squashed коммитами в master, но в их использовании нет реальной необходимости если не принуждать разработчиков каждый коммит в их фиче-бранчах оформлять в этом стиле.


Вообще, основная польза этой спецификации не в том, что она задаёт правила оформления коммитов, а в том, что она приводит к линейной истории, состоящей из осмысленных и цельных изменений, которую можно обрабатывать утилитами для автоматизации механических действий вроде подготовки changelog или выбора номера следующей версии для релиза. Иными словами, суть спецификации составляют 4 термина: squash, feat, fix, BREAKING CHANGE — именно они создают ценность. Всё остальное можно поменять, и ничего принципиально не изменится.


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

Спасибо за комментарий! Действительно часть советов и рекомендаций ошибочно попала в блок тезисов конвенции Conventional Commits. Внес корректировки. Благодарю за внимательное прочтение статьи. Ни в коем случае не хотел ввести кого-то в заблуждение. Сам люблю порядок и ценю точность формулировок.
А если просто <НОМЕР-ЗАДАЧИ-В-ТРЕКЕРЕ> и сквошить все комиты? 1 комит — 1 задача. Кому интересно, пойдет в джиру и посмотрит, не?

Лично я против. Это смена контекста. К тому же, возможно, такое, что тикет переоткрывали не раз, и тогда придётся сравнивать время комментариев и коммита.
Джира может быть и недоступна по разным причинам (работаю дома, интернет отвалился, etc).
Ну, а кроме того, убеждён, что человек, пишущий осмысленный текст, чётче начинает понимать, что же он сделал, и, возможно, даже поймёт, что сделал не всё или не так

Или что надо то, что он сделал разбить на два коммита и, может даже, завести отдельную задачу на «лишнюю» часть.
#номер_стори название стори
Зачем придумывать велосипеды? (и да, сквошить все чейнджи в один коммит при PR, чтобы не мусорить в мейне, и нет, имена коммитов в фичабранче не интересуют вообще никого и никогда)

Поддержу коллег выше. Коммит должен иметь форму: номер тикета: название тикета.
Один коммит должен относиться к одному тикету. Если у вас тикеты связаны между собой то линкуйте их в Jira или что там у вас еще. Тикет — единственное место, куда кто-то еще смотрит. Коммит мессадж никто не читает.

Коммит должен иметь форму: номер тикета: название тикета.

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


Один коммит должен относиться к одному тикету.

Если тикет маленький и локальный — конечно да.
А что делать если тикет большой и по логике разбивается на несколько крупных независимых изменений?

Несколько коммитов на тикет не нарушают правила «Один коммит должен относиться к одному тикету»

Но нарушают предыдущее Коммит должен иметь форму: номер тикета: название тикета.
Или вы видите смысл в нескольких коммитах с одинаковым комментарием?


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


Но что делать когда каждый тикет описывает свою проблему часть которой фиксит твой коммит?

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

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

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

В описанном в статье виде получается часть информации в тикете, а часть в коммите.
Да, получается, и ничего плохого в целом в этом не вижу. И основная цель сообщения коммита не как можно быстрее перебросить человека куда-то, а дать человеку возможность получить нужную ему информацию прямо из первой строки сообщения и принять решение нужно ли дальше этот коммит рыть хоть в тиккет-системе, хоть смотреть список измененных файлов и собственно изменения, или пропустить его и смотреть другой.
Если вы делаете agile/scrum в команде, то любая story/задача/баг whatever, должна быть на канбан борде с уникальным номером. Как правило, мы в команде указываем номер story с тайтлом при коммите. Так что никаких вопросов не возникает у членов команды. А если же у вас каждый разраб делает комиты и никто потом не может понять что именно правилось и для чего, то здесь пару проблем. 1-ая — вы не делаете agile и каждый разраб получает задачи индивидуально, 2-ая — вы не делает pair programming/mobbing/code review в команде. И как результат, очень слабая коммуникация внутри команды.
Нет, не диктует. Но так принято в любом скрам тиме иначе как потом искать таск в жире или любом другом багтрекере?
Некоторые скрам команды довольствуются скрам доской с листочком и счастливы вполне без всякого треккера кроме лога гита.
Все правильно пишут про номера тикетов. Разумное именование коммитов — утопия, под которую можно подвести только процентов 50% изменений.

Мы в компании пользуемся гитхабом, и там метаинформация побогаче. PR линкуется к тикету или связанным тикетам. Тикет рассказывает, ЧТО мы делаем / фиксим. В описании PR я кратко описываю КАК мы это делаем (если это не очевидное устранение, допустим, опечатки). Таким образом остаются какие-то более-менее адекватные следы.

Под конкретный тикет определить каждый коммит тоже может быть затруднительно, особенно если треккер не поддерживает иерархии типа эпик-стори-таск-подтаск, а чисто плоский списко тасков
Спасибо, полезная статья. Честно говоря на работе уже кровь течет из глаз, когда в очередной раз видишь такие коммиты:
fix
fix
fix
done
Речь идет о перезаписи рабочей ветки, т.е. над которой работает один разработчик до ее вливания, исключительно в этом случае нулевая опасность.
1) при перезаписи всегда есть шанс что-то важное потерять. Перезапись делается чтобы что-то потерять, но всегда есть шанс, что потеряется не только то, что хотел, но и что-то ещё.

2) если «вливание» — это мерж или типа того, то есть, например, кодревью перед ним при котором ветка стягивается на машину другого разработчика и он может попросить сделать какие-то изменения. Ревью этих изменений в перезаписанной ветке составляет проблему.

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

Вот потому я всегда советую делать squash в отдельном бранче.


Как?


Допустим, у нас есть master, работали мы в feature.


В feature миллион мелких правок, которые нас раздражают и которые мы хотим убрать.


git checkout feature
git merge master
git checkout -b merge_feature
git rebase -i master


Дальше оставляем один или больше коммитов как pick, а все остальные (которые мусор) помечаем как squash. На выходе имеем:


а) Чистую историю для merge'а
б) Грязную историю для истории
в) Минимальные шансы что-то сломать. Сломаем — удаляем бранч merge_feature и делаем заново.

Не удалось подружиться из-за commit.gpgsign=true
Хуки запускаются до того, как будет введет пароль

Тут есть два аспекта: первое — машиночитаемость описания коммита. Всякие фиксированные теги, scope и т.д.


Второе — семантика. Вот о семантике люди как раз и забывают. Семантика — это смысл изменения. Не "что было поменяно" (это видно в диффе), не где было поменяно (это тоже было в диффе), а почему.


При этом есть ещё одна проблема — это контекст. Если я только что потратил час, разбираясь, почему в svg у стрелочек неправильный угол, то мой контекст предельно глубокий (высокий?) — "fix#2 for incorrect calculation of project plane".


Заметим, для человека в том же контексте этот коммит полностью осмысленный. Он даже говорит, что именно было поправлено.


А теперь представьте себе, что это коммит в проект в котором 800к строк и фиксились стрелки в крайне специфичном режиме, о существовании которого и не все разработчики знают?


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


Не все коммиты это требуют, но бывают коммиты, в которых текст значит больше, чем код. Например "Use ASCII for progress bar. In a few terminal models (dump & vt100, etc) they can not be rendered and causing distortion. We can't use ncurses here as it is loaded later.".


Вот это "we can't use" — самое ценное в этом коммите.

Вот это "we can't use" — самое ценное в этом коммите.

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


Детальное описание коммита — это мета-данные изменения. Их редко читают, а когда читают, то обычно хотят узнать зачем вообще делался этот коммит. Не почему он внёс именно такие изменения, и не какие именно изменения он внёс, а для чего вообще понадобилось данное изменение. Обычно для этого вполне достаточно одной фразы в стиле conventional commit и/или ссылки на issue.


Конкретно в Вашем примере хорошим сообщением коммита было бы: "fix: progress bar rendering for some terminal models".

Во, вы считаете, что коммиты редко читают. А я вот, по своей работе, больше читаю описания коммитов, чем исходных текстов.

В общем случае объяснение «почему не» или «почему пришлось так», лучше всего сохранять в описании коммита, а не в комментарии. Потому что комментарий может остаться и при рефакторинге (зачем умный комментарий стирать?), а в коммите он привязан к конкретному изменению.
Я для себя понял что хочется scope делить на техническую и бизнесовую часть (домен). Подробнее.

Примеры:

shopCard.amount/style/mod: #27 outline — изменили стиль аутлайна для инпута суммы на корзине

shopCard/test/add: #28 snapshots — добавлено снапшот-тестирование для корзины

app/build/fix: #29 reduce bundle size
Only those users with full accounts are able to leave comments. Log in, please.