Коли дрібниці важливі. Пишемо коміти в Git
Усім привіт, мене звуть Ілля, я Software Engineer у Dev.Pro. Ця стаття — про коміти та їхню надважливу функцію у житті розробника. Вона стане у пригоді тим, хто хотів би навести лад у git history і changelogs, а заодно поліпшити комунікацію.
In case of fire git commit → git push → git out.
Цей колись смішний жарт бачила, мабуть, кожна людина, що має хоч якийсь стосунок до IT. Коміти — це цінна штука, але водночас буденна, хоча так було не завжди. Ще кілька років тому заливати зі схрещеними пальцями апдейти по FTP було так само поширеною практикою, як сьогодні «коміт → пуш → додомку». І якщо з останніми двома кроками все більш-менш зрозуміло, то про те, як робити класні коміти, нерідко виникають суперечки.
Ілюстрація Аліни Самолюк
Основи
Отже, я вирішив поглянути на те, що відбувається у світі стосовно комітів, почитати, що пишуть розумні люди, і порівняти це з власним досвідом. Виявилось, що «гарний коміт» описують набором порад, який має плюс-мінус однаковий вигляд:
- Відділяйте заголовок коміта від його тіла порожнім рядком.
- Пишіть заголовок, що містить не більше як 50 символів.
- Починайте заголовок з великої літери.
- Не ставте крапку в кінці заголовку.
- Не пишіть у рядку тіла коміта більше ніж 72 символи.
- Позбудьтесь непотрібних знаків пунктуації.
- Додавайте тіло коміта тільки за потреби: текст має пояснювати зміст змін.
- Використовуйте імператив у заголовку.
Приклади того, яким має бути коміт згідно з цими рекомендаціями, ретельно розібрані у цій статті.
Більшість рекомендацій тісно пов’язані з правилами англійської граматики та командами git format-patch та send-email. Наприклад, порожній другий рядок означатиме, що перший — це заголовок листа, а все інше — сам текст повідомлення. Правило про довжину рядка залишилось на пам’ять від старих терміналів з обмеженням ширини у 80 символів і відповідного робочого етикету. А правило про імператив у заголовку виведено для того, щоб успадкувати тон автоматичних комітів, які генеруються самим Git під час merge/revert операцій.
Список ніби зрозумілий, і навіть є мотивація за кожним із цих пунктів. Але ось проблема: ці правила були описані у 2008 році. Тобто 12 років тому. Для ІТ — ціла ера, чи не так?
Як це працює сьогодні
За цей час зазнало змін майже все. І точно змінився набір інструментів, які використовують команди під час розробки: починаючи від каналів комунікації, як-от Zoom і Slack, і до IDE, які сьогодні можуть значно більше, ніж
Звісно, для маленьких проєктів, які люди пишуть для себе і не планують нікому показувати, найголовнішим, найімовірніше, залишиться критерій зручності для автора. Цікавіше поговорити про роботу з іншими людьми. Мій перший вчитель в 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.
Замість висновків
Для мене найбільшою цінністю гарного коміта є номер задачі в таск-трекері. Вся інформація — там (працюю разом із чудовою командою бізнес-аналітиків, люблю їх). Гарно описане завдання, та ще й з коментарями, пояснить все набагато краще, ніж дуже вдалий коміт.
У коміті можна написати, що саме змінилося, а із задачі зрозуміло чому. Знаючи причини, на ситуацію можна подивитися з іншого ракурсу, і майже завжди цей ракурс буде вигіднішим. Тому коли я відкриваю анотації до файлу і з коміта розумію, де можна подивитись всю інформацію, то економлю купу часу, мені не треба ходити дізнаватись усю історію — вона доступна майже одразу.
Хочеться також відзначити, що, поки гарний заголовок спрощує життя колегам, тіло коміта спрощує життя самому кодеру. Над завданням можна працювати і декілька днів, втратити контекст, відриватися на більш важливі речі, а потім повернутись до оформлення пул-реквесту і сидіти видивлятись у своїх комітах, що ж саме змінилось. На щастя, тіло коміт-меседжа автоматично підтягується в текстове поле і це суттєво полегшує завдання автору пул-реквесту: гарний опис майже готовий, вся інформація під рукою. Це ніби прості речі, але вони дуже корисні на фінальній стадії роботи над завданням.
Отже, якісний коміт у
- Обговорений і закріплений формат.
- Pre-commit хуки і лінтер.
- Номер задачі в таск-трекері в заголовку коміта.
- Список змін у тілі коміта.
P.S. Я працюю у великій команді, хуки у нас були не завжди, й можу на власному досвіді стверджувати, що рішення про використання їх у репозиторії було дуже важливим. Ми почали писати однакові коміти, і відпала купа дивних проблем. Тож, якщо ви ще не мали нагоди їх застосовувати або якраз думаєте про це, дуже рекомендую. Часу на інтеграцію обмаль, а вплив і зростання якості важко переоцінити!
Щоби не пропустити нові статті Іллі Хлєбова — підписуйтеся на нього у телеграм-боті Стрічки DOU.