Коли дрібниці важливі. Пишемо коміти в Git

Усім привіт, мене звуть Ілля, я Software Engineer у Dev.Pro. Ця стаття — про коміти та їхню надважливу функцію у житті розробника. Вона стане у пригоді тим, хто хотів би навести лад у git history і changelogs, а заодно поліпшити комунікацію.

In case of fire git commit → git push → git out.

Цей колись смішний жарт бачила, мабуть, кожна людина, що має хоч якийсь стосунок до IT. Коміти — це цінна штука, але водночас буденна, хоча так було не завжди. Ще кілька років тому заливати зі схрещеними пальцями апдейти по FTP було так само поширеною практикою, як сьогодні «коміт → пуш → додомку». І якщо з останніми двома кроками все більш-менш зрозуміло, то про те, як робити класні коміти, нерідко виникають суперечки.

Ілюстрація Аліни Самолюк

Основи

Отже, я вирішив поглянути на те, що відбувається у світі стосовно комітів, почитати, що пишуть розумні люди, і порівняти це з власним досвідом. Виявилось, що «гарний коміт» описують набором порад, який має плюс-мінус однаковий вигляд:

  1. Відділяйте заголовок коміта від його тіла порожнім рядком.
  2. Пишіть заголовок, що містить не більше як 50 символів.
  3. Починайте заголовок з великої літери.
  4. Не ставте крапку в кінці заголовку.
  5. Не пишіть у рядку тіла коміта більше ніж 72 символи.
  6. Позбудьтесь непотрібних знаків пунктуації.
  7. Додавайте тіло коміта тільки за потреби: текст має пояснювати зміст змін.
  8. Використовуйте імператив у заголовку.

Приклади того, яким має бути коміт згідно з цими рекомендаціями, ретельно розібрані у цій статті.

Більшість рекомендацій тісно пов’язані з правилами англійської граматики та командами git format-patch та send-email. Наприклад, порожній другий рядок означатиме, що перший — це заголовок листа, а все інше — сам текст повідомлення. Правило про довжину рядка залишилось на пам’ять від старих терміналів з обмеженням ширини у 80 символів і відповідного робочого етикету. А правило про імператив у заголовку виведено для того, щоб успадкувати тон автоматичних комітів, які генеруються самим Git під час merge/revert операцій.

Список ніби зрозумілий, і навіть є мотивація за кожним із цих пунктів. Але ось проблема: ці правила були описані у 2008 році. Тобто 12 років тому. Для ІТ — ціла ера, чи не так?

Як це працює сьогодні

За цей час зазнало змін майже все. І точно змінився набір інструментів, які використовують команди під час розробки: починаючи від каналів комунікації, як-от Zoom і Slack, і до IDE, які сьогодні можуть значно більше, ніж 2008-го. Змістився і фокус уваги кодера: більше не потрібно шукати правди в коментах до коду або в тексті коміту: процес розробки став доволі цілісною штукою з вибудованою інфраструктурою. Середньостатистичний аутсорс-проєкт радше користується JIRA і Bitbucket, а не розсилкою патчів електронною поштою. Так що, якщо потрібно щось прочитати чи дізнатись, я просто відкриваю тікет і читаю. Або вікі, або ще щось, що під’єднане до інфраструктури проєкту.

Звісно, для маленьких проєктів, які люди пишуть для себе і не планують нікому показувати, найголовнішим, найімовірніше, залишиться критерій зручності для автора. Цікавіше поговорити про роботу з іншими людьми. Мій перший вчитель в IT навчав так: «Пишіть код таким чином, ніби після вас його буде підтримувати людина з маніакальними садистськими нахилами». Ми сміялися з цього: ну хіба ж може таке бути, щоб в IT працювали маніяки? Тут же всі такі гарні, розумні й милі!

Виявилось, що «маніакальні» здібності можуть прокинутись і в тобі самому, особливо тоді, коли бачиш коміт, в якому автор змінив 12 файлів в ядрі й лаконічно написав WIP. Яка саме робота була «in progress» в той момент, коли цей коміт з’явився, і які цей код розв’язує задачі, доведеться здогадуватись без пояснень. Схоже трапляється через те, що немає жодних домовленостей щодо того, якими мають бути коміти. Щоб такого не було, треба це узгоджувати.

У кожному конкретному випадку домовленості можуть трохи відрізнятися, але принцип буде схожим: коміту потрібен формат. Якщо він відповідає цьому формату — коміт ок, якщо ні — не ок. Постає питання: як визначити цей формат і як перевіряти коміт на відповідність.

Є кілька опцій:

  • Щоб не вигадувати черговий велосипед (хіба нам своїх мало?) можна взяти за основу той самий формат, яким користується більшість, або ваш основний фреймворк. Наприклад, пишете на Angular — подивіться, як вони комітять код свого фреймворку, може, в них є політика або гайдлайн.
  • Можна пошукати якийсь відомий підхід з хорошою документацією. Наприклад, Conventionalcommits.org. Він добре описаний, має достатню кількість посилань на різний допоміжний тулінг, а ще його автори хоча й пишуть, що базують концепцію на попередньому пункті, але все ж не прив’язуються ні до якого фреймворку. Так що його можна використовувати будь-де, не витрачаючи час на відповіді на закономірні запитання типу «чому у нас проєкт на PHP, а conventional commit — ангулярівський?».
  • Виходити з можливостей своєї інфраструктури. Майже всі користуються JIRA, чи не так? А точніше навіть JIRA+Bitbucket. У них є такий зручний інструмент — смарт-коміти. Якщо коротко, то одним комітом можна затрекати час, залишити коментар до відповідного тікета і змінити йому статус. Усе, що треба — дотримуватись формату й налаштувати цю фічу на своєму проєкті.

Усі вищенаведені варіанти — про формат заголовку. Перевірка на відповідність формату виконується за допомогою pre-commit hooks, які порівнюють текст із певною регуляркою. Наразі одним із найпопулярніших git hook runner + linter рішень є поєднання husky і commitlint.

В результаті матимемо husky pre-commit hook, який буде спрацьовувати щоразу, коли автор хоче зробити коміт, commitlint, який буде дивитись на свої конфіги й перевірятиме, чи відповідає текст коміту усім зазначеним правилам.

Такий простий сетап вирішує цілу низку питань: від загальної невизначеності щодо формату комітів до конкретних проблем з боку CI. Наприклад, одного разу специфічні для Windows символи, що потрапили в коміт-меседж із домашньої машини одного із тіммейтів, виявились сильнішими за build-скрипт. Зрозуміло, що це можна вирішити різними способами, але чи не краще розв’язувати проблеми саме там, де вони виникають?

Коли проблеми вирішено, варто перейти до питань автоматизації релізів. Це також дуже зручно робити, якщо у вас є домовленість про формат комітів. Припустимо, ви узгодили, що є задачі трьох типів: fix, task, improvement. Також ви погодили, що формат коміту матиме таку схему: type(scope?): subject, де type — це тип задачі, scope — домен або частина проєкту, до якого вона належить. І subject — це, власне, те, які зміни відбулися. Додавши до цього інструменти автоматизації, отримаємо зручні й вичерпні release notes для кожної нової версії. Вони матимуть приблизно такий вигляд:

Гарно, правда? Цей слайд взятий з чудової презентації Mario Nebl.

Замість висновків

Для мене найбільшою цінністю гарного коміта є номер задачі в таск-трекері. Вся інформація — там (працюю разом із чудовою командою бізнес-аналітиків, люблю їх). Гарно описане завдання, та ще й з коментарями, пояснить все набагато краще, ніж дуже вдалий коміт.

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

Хочеться також відзначити, що, поки гарний заголовок спрощує життя колегам, тіло коміта спрощує життя самому кодеру. Над завданням можна працювати і декілька днів, втратити контекст, відриватися на більш важливі речі, а потім повернутись до оформлення пул-реквесту і сидіти видивлятись у своїх комітах, що ж саме змінилось. На щастя, тіло коміт-меседжа автоматично підтягується в текстове поле і це суттєво полегшує завдання автору пул-реквесту: гарний опис майже готовий, вся інформація під рукою. Це ніби прості речі, але вони дуже корисні на фінальній стадії роботи над завданням.

Отже, якісний коміт у 2020-му це:

  1. Обговорений і закріплений формат.
  2. Pre-commit хуки і лінтер.
  3. Номер задачі в таск-трекері в заголовку коміта.
  4. Список змін у тілі коміта.


P.S. Я працюю у великій команді, хуки у нас були не завжди, й можу на власному досвіді стверджувати, що рішення про використання їх у репозиторії було дуже важливим. Ми почали писати однакові коміти, і відпала купа дивних проблем. Тож, якщо ви ще не мали нагоди їх застосовувати або якраз думаєте про це, дуже рекомендую. Часу на інтеграцію обмаль, а вплив і зростання якості важко переоцінити!


Щоби не пропустити нові статті Іллі Хлєбова — підписуйтеся на нього у телеграм-боті Стрічки DOU.

Похожие статьи:
Furniture refers tо movable оbjесtѕ intеndеd to ѕuрроrt vаriоuѕ humаn асtivitiеѕ such as ѕеаting (e.g., сhаirѕ, stools, аnd sofas), eating (tаblеѕ), and ѕlеерing (е.g., bеdѕ). Furniturе iѕ аlѕо uѕеd tо hold...
Всем привет! В феврале произошло много чего интересного. Во-первых, Ruby исполнилось 25 лет, о чем написал Матц в своем Твиттере. Во-вторых,...
Приветствую вас, уважаемые читатели DOU! Меня зовут Вадим. Прочитав множество статей в разделе о релокации, я так и не нашел человека,...
Кабінет міністрів України доповнив перелік дозволених у рамках спеціального правового й податкового простору Дія City видів...
Вскоре после официального подтверждения наличия 4 ГБ оперативной памяти и поддержке сетей четвертого поколения в смартфоне...
Яндекс.Метрика