İyi Bir Commit Nasıl Olmalı?

"asd", "asdfg", "update" gibi commit mesajlarını eminim çoğumuz yapmışızdır. Aslında buradaki commit komutunu "kaydetme butonu" olarak değil de projenin geliştirme günlüğündeki anlamlı bir cümleye benzetirsek daha doğru olur.

Bir yıl sonra dönüp baktığımızda (veya takım arkadaşımız bir saat sonra baktığında) ben bunu neden yapmıştım sorusunun cevabını bulabilmeliyiz.

Commit Yaparken Şunları Gözönünde Bulundurun

Madem commit'ler projenin günlüğüdür dedik, o halde bu defteri temiz tutmak için standartlaşmış uyulması gereken bazı altın kurallar var. Gelin bunlara birlikte bakalım. İşte git commit -m "mesaj" komutunu çalıştırırken dikkat etmemiz gerekenler.

Atomik Commit (küçük ve öz)

İyi bir commit atomik olmalıdır yani tek bir işi yapmalıdır. Bunu yazılımdaki SOLID prensiplerinden Tek Sorumluluk (Single Responsibility) prensibiyle örtüştürebiliriz.

  • Yanlış: Hem butonun rengini değiştirip hem veri tabanı bağlantı hatasını düzeltip tek commite sığdırmak.
  • Doğru: Bu iki geliştirmeyi iki farklı commit olarak göndermek.
  • Neden? Veri tabanı düzeltmemiz patlarsa sadece onunla ilgili olan commit'i geri alabiliriz (revert).

Mesajın Anatomisi: 50/72 Kuralı

Yazılım dünyasında standartlaşmış bir commit yapısı vardır. Bu kural yazılı olmayan fakat evrensel olarak kabul görmüş kurallardan biridir. Bu yapı logları okurken göz yorgunluğunu önler.

  • Başlık: Maksimum 50 karakter olmalıdır. Değişikliğin çok kısa özetidir, bir bakışta neyi ifade ettiğini zorlanmadan anlamamız gerekir.
  • Boş Satır: Başlık ile gövde arasına boş satır bırakırsak hem okuyucunun işini kolaylaştırırız hem de GitHub/GitLab gibi platformlar bu şekilde başlığı gövdeden ayırır. İyi bir alışkanlıktır.
  • Body: Gerekli detayların yazıldığı yerdir. Satırların maks. 72 karakter olması önerilir yani satır 72 karakteri aştığında gerçekten alt satıra (hard wrap) geçmelidir (bu terminalde okumayı kolaylaştıracaktır).

Doğru Dil: Emir Kipi

Bu aslında biraz göreceli bir konu olsa da genel kabul emir kipiyle yazılması yönündedir.

  • Yanlış: "Kullanıcı girişi eklendi", "Kullanıcı girişi ekliyorum"
  • Doğru: "Kullanıcı girişi ekle"
Yazdığımız başlığın doğru olup olmadığını anlamak için şu sihirli cümleyi kullanabiliriz: "Eğer uygulanırsa, bu commit [başlığımız]." (If applied, this commit will [your commit message]). Eğer cümleyi okuduğunuzda anlamlı oluyorsa başlığınız doğrudur.

"Nasıl" Değil, "Neden" ve "Ne" Açıklanmalı

Yaptığımız bir değişikliğin nasıl çalıştığını uzun uzun yazmamıza gerek yoktur çünkü kod zaten oradadır. Commit mesajının gövdesi şuna cevap vermelidir:

  • Bu değişiklik neden gerekliydi?
  • Bu commit ne yapıyor?
  • Varsa yan etkileri veya diğer modüllere etkileri nelerdir?

Bunu bir örnekle açıklayacak olursak

  • Kötü örnek (Nasıl'ı anlatan): "Kullanıcı listesindeki for döngüsü silindi, yerine map() fonksiyonu eklendi ve i değişkeni kaldırıldı." (Bunu zaten kod değişikliklerine bakınca görebiliyoruz)
  • İyi Örnek (Neden'i ve Ne'yi anlatan): "Kullanıcı listesi yüklenirken yaşanan performans darboğazı giderildi. Veri işleme süresini kısaltmak için eski döngü yapısı yerine map() kullanımına geçildi."

İzlenebilirlik (Traceability)

Eğer Jira, Trello, GitHub Issues gibi proje yönetim araçları kullanılıyorsa commit mesajında ilgili görevin referans numarası (örn: TICKET-10) yer almalıdır. Bu durum, entegre olunan platformda iş akışını takip etmeyi kolaylaştırır. Örnek kullanım: fix: kullanıcı girişindeki validasyon hatasını düzelt (TICKET-10)

Çalışmayan Kod Commit Edilmemeli

Eğer işimiz bitmediyse veya bozduysak ve bilgisayar başından kalkmamız gerekiyorsa bunu ana veya ortak dallara (main, develop vb.) kesinlikle göndermemeliyiz. Özellikle ekip çalışmalarında ve CI/CD (sürekli entegrasyon) süreçlerinin olduğu projelerde ana dallara (main/develop) çalışmayan kod göndermek çok tehlikelidir. Böyle durumlarda kendimize branch açmak veya git stash komutunu kullanmak seçeneklerimiz arasındadır.

Örnek Şablon

örnek şablon
Başlık
Kısa ve öz bir başlık (maksimum 50 karakter ve emir kipi)

Gövde
Değişikliğin neden yapıldığını açıklayan detaylı gövde metnini
buraya yazın. Satırların 72 karakteri geçmemesine özen gösterin ki terminalde
okuması kolay olsun. Sorunu neyin çözdüğünü ve varsa
alternatif yaklaşımları neden reddettiğinizi açıklayın. Takip kodu (varsa) Çözülen Issue #10

Bonus: Conventional Commits (Geleneksel Commit'ler)

Günümüzde birçok popüler açık kaynaklı proje ve kurumsal şirket, commit mesajlarına belirli bir ön ek (prefix) koyma standardını benimsiyor. Bu yapıyı, hem insanların hem makinelerin anlayabileceği ortak bir dil olarak düşünebiliriz. Ayrıca otomatik sürüm (versiyon) notları oluşturmayı kolaylaştırır. Bu standardın resmi spesifikasyonunu ve tüm detaylarını conventionalcommits.org adresinden inceleyebilirsiniz. En yaygın kullanılan ön ekler şunlardır:

  • feat: Yeni bir özellik eklendiğinde. (Örn: feat: kullanıcı profil sayfası ekle)
  • fix: Bir hata giderildiğinde. (Örn: fix: şifre sıfırlama maili hatasını çöz)
  • refactor: Ne yeni bir özellik ekleyen ne de hata düzelten, sadece mevcut kodun yapısını iyileştiren değişiklikler. (Örn: refactor: veri çekme fonksiyonunu basitleştir)
  • docs: Sadece dokümantasyon güncellemeleri. (Örn: docs: README dosyasına kurulum adımlarını ekle)
  • style: Kodun çalışmasını etkilemeyen formatlamalar (boşluk, noktalı virgül vb.). (Örn: style: gereksiz boşlukları sil ve girintileri düzenle)

Toparlamak Gerekirse

Başlangıçta tüm bu kurallara uymak biraz zaman alıcı veya yorucu gelebilir. Ancak bu standartları bir kez alışkanlık haline getirdiğinizde, aylar sonra kendi kodunuza dönüp baktığınızda (veya yeni bir ekip arkadaşınız projeye dahil olduğunda) kendinize teşekkür edeceksiniz. Unutmayın; yazdığınız kod makine içindir ama commit mesajlarınız insanlar içindir. Temiz loglar ve bug'sız günler dilerim!