Conventional Commits ile Commit Mesajlarında Aynı Dili Konuşmak

Tuğsan Ünlü
4 min readNov 29, 2020
Conventional Commits

Girizgah

Çalıştığımız projelerde yaptığımız değişiklikleri, kullandığımız versiyon kontrol sistemlerine commitlerken değişikliklerimizi açıklayan kısa metinleri commit mesajları olarak yazıyoruz. Bu mesajlar çalışılan ekipler içerisinde ortak bir akıl ile belirlenip standartlaştırılabildiği gibi kimi zaman da geliştiricilerin inisiyatifine bırakılabiliyor. Problem de aslında bu inisiyatifin kötüye kullanılmasından doğuyor.

Neden ihtiyaç var?

Geliştiriciler olarak zaman kısıtlılığı, projenin sürekliliğine işin kendisini yapmaktan görece daha az değer atfetmek gibi sebeplerden ötürü işin çalışabilirliğini etkilemeyecek yan unsurları göz ardı edebiliyoruz. Bu görüş, kısa vadede çok hızlı işler çıkmasını sağlarken uzun vadede teknik borçları beraberinde getiriyor.

Teoride hiç kimsenin geliştirme tarihçesinde fix. veya HATA ÇÖZÜLDÜ gibi nereyi işaret ettiği belli olmayan, anlamsız bir commit mesajı görmek istemeyeceğini düşünsek de pratikte maalesef yukarıda saydığım sebeplerden ötürü bunlara şahit oluyoruz.

Her ne kadar versiyon kontrol sistemlerinin sunduğu muhtelif araçlarla tarihçelerimizi daha sonra yeniden düzenleyebilsek de Robert C. Martin’in Clean Code kitabında atıfta bulunduğu LeBlanc yasasının “Sonra asladır. (Later equals never.)” varsayımını unutmamak gerekiyor.

“Sonra asladır.”

Commit mesajlarının yönetimi, bu açıdan pek göze görünmeyen fakat projelerin geliştirme tarihçesini kişi veya ekstra belgelendirmelere ihtiyaç duymadan anlatabildiği için çok kıymetli bir alan.

Conventional Commits, commit mesajlarında herkesin aynı dili kullanmasını amaçlayan bir proje. Mottosunda belirtildiği gibi insanlar ve makineler tarafından okunabilen commit mesajları oluşturmayı hedefliyor. Bunu yaparken semantik versiyonlamanın nimetlerinden faydalanıyor.

Bir commit mesajının anatomisi

Conventional Commits, commit mesajlarını ilk olarak sırasıyla tip, kapsam ve mesaj olarak anlamlı parçalara ayırıyor. Günün sonunda aşağıdaki formatta bir mesaj yazılmasını bekliyor.

tip(kapsam): mesaj 

Tip

Tip, değişikliğin hangi amaçla yapıldığını belirtiyor ve varsayılan olarak fix, feat, build, chore, ci, docs, style, refactor, perf ve test değerlerini alabiliyor.

Kapsam

Kapsam bu değişikliğin hangi alanda yapıldığını, değişiklikten projenin hangi bölümünün etkilendiğini belirtiyor. Yazılması zorunlu bir alan değil ama yazıldığında asıl commit mesajını kısa ve net tutmaya yarıyor. Bu yüzden zorunlu bir alanmış gibi ele alınmasında bir zarar yok bence.

Mesaj

Mesaj ise zaten değişiklikle ilgili yazmak istediğimiz metni ifade ediyor. Projenin kendisi mesaj metninin içeriğinin nasıl olması gerektiğiyle ilgili doğrudan bir şey söylemiyor. Fakat ne koşulda olursa olsun tutarlı olmasını istiyor. Yani mesajlar küçük harfle yazılmaya başlandıysa tamamının küçük harfle yazılmasını istiyor. Bu kuralları ekstra araçlarla genişletebiliyoruz, birazdan bahsedeceğim.

Semantik versiyonlamanın konumu

Bilindiği gibi semantik versiyonlamada değişiklikler majör, minör, patch -ve kimi zaman bunlara ek olarak build- olarak farklı kategorilerde ele alınıyor. Daha önce yazdığım NPM ile Semantik Versiyonlama Nasıl Kullanılır? yazısında bundan uzun uzadıya bahsetmiştim.

Conventional Commits ile belirtilen tipler de proje tarihçesinden bir semantik versiyonlama çıkarmamızı sağlıyor. Breaking change olarak isimlendirilen kapsamlı, geriye dönük uyumluluk içermeyen değişiklikler commit mesajlarında ! ile gösteriliyor. Bunlar semantik versiyonlamadaki majör değişikliklere karşılık geliyor. Hemen bir örnek verelim.

refactor!: internet explorer desteği sonlandırıldı

Bununla birlikte feat yani feature tipi semantik versiyonlamadaki minör değişikliklere, fix tipi ise patch değişikliklerine karşılık geliyor.

Otomatikleştirme

Tıpkı Prettier, ESLint gibi araçlara yazdığımız kodları taratıp konvansiyona uymayan format veya kullanımlar konusunda bizi uyarmalarını sağladığımız gibi Commitlint araçlarıyla da commit mesajlarının Conventional Commits projesine uygun olup olmadığını denetleyebiliyoruz. Benim kullanım önerim kesinlikle bu yönde. Çünkü günün sonunda tüm sorumluluğu kişilere bıraktığımızda yine yukarıdakilere benzer kötü senaryolar yaşanması çok muhtemel.

Commitlint araçları, proje içerisinde olmayan fakat oldukça faydalı ek özellikler de sunuyor. Commit mesajlarının belli bir karakterden uzun olmaması, içerisinde nokta veya özel işaretler olmaması, tamamının küçük harfle yazılması, mesajların sonuna yapılan değişiklikle ilgili Jira vb. proje yönetim araçlarındaki issue numaralarının eklenmesi gibi oldukça kullanışlı özellikleri mevcut.

Bu kontrolleri Git’in pre-commit veya pre-push kancalarına ekleyerek formatı doğrulanmamış commit mesajlarının repolara girişinin engellenmesi sağlanabiliyor. Başta bu kurallara uymak ekstra bir uğraş gerektiriyor gibi gözükse de çok kısa zamanda alışılıp birer meleke hâline geldiğinde arkada bir lint aracının çalıştığı dahi unutuluyor.

Ne sağlıyor?

Üstüne bu kadar laf ettim ama son olarak tüm bunların ne sağladığını da kısaca özetleyerek bitireyim.

Conventional Commits kurallarına uyulduğunda;

  • Ekstra hiçbir efor harcamadan projelere dair bir değişiklik günlüğü (changelog) otomatik olarak oluşuyor.
  • Kolayca semantik versiyonlama yapılabiliyor.
  • Hangi projenin, hangi kapsamında, hangi türde geliştirmeler, iyileştirmeler, hata düzeltmeleri yapıldığı raporlanabiliyor.
  • Jira, Trello gibi proje yönetim araçlarındaki iş detaylarından spesifik olarak ilgili işin yaşam döngüsü izlenebiliyor.
  • Kalabalık ekiplerde aynı dilin konuşulmasını, kişilerin, başkalarının yaptığı değişiklikleri çok daha kolay anlaması sağlanıyor.
  • Çıktı olarak sürüm takibi tarihçeleri üzerine analiz yapabilecek araçlar için düzenli bir veri seti oluşturuyor.
  • Belirtilen tiplere göre otomasyon araçları geliştirmeye veya operasyonel işlemler yürütmeye (tip alanında “ci” görülen commit mesajlarının deployment pipeline’larını tetiklemesi, “test” görülenlerin birim veya uçtan uca testleri tetiklemesi vs. gibi.) imkânlar tanınıyor.

Bu yazıyı şimdilik burada bitiriyorum. Bir sonraki yazı olarak bahsettiğim tüm bu denetleme süreçlerinin bir Front-End projesinde nasıl uygulandığından bahsetmek niyetindeyim.

Kaynaklar

https://www.conventionalcommits.org/en/v1.0.0/
https://github.com/conventional-changelog/commitlint
https://xkcd.com/1296/
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
https://semver.org/

--

--