Geliştirici Araçları kod örnekli
Git Hook ile Kalite Kapısı: pre-commit Kurulumu
Kod incelemesinde tartışılan şeylerin çoğu makinenin işi: boşluk, sıralama, unutulmuş debug satırı, yanlışlıkla eklenmiş anahtar. Bunları commit anında yakalamak, insan dikkatini asıl işe bırakıyor.

İçindekiler
Bu yazıyı dinle
Yapay zekâ sesiyle yaklaşık 2 dakikalık özet
Git hook kalite kapısı kurmak, kod incelemelerini gereksiz tartışmadan kurtarmanın en ucuz yolu. İnceleme yorumlarınıza bakın: "boşluk fazla", "burada var_dump kalmış", "import sırası bozuk". Bunların hiçbiri insan dikkati gerektirmiyor. Makineye devredildiğinde inceleme, gerçekten insan gerektiren şeye — kodun doğru şeyi yapıp yapmadığına — odaklanabiliyor.

Hook nedir, ne zaman çalışır?
Git, belirli olaylarda depodaki betikleri çalıştırır. Üçü pratikte işe yarar:
pre-commit— commit oluşturulmadan hemen önce. Sıfır çıkış kodu dönmezse commit iptal edilir.commit-msg— mesaj yazıldıktan sonra. Mesaj biçimini denetlemek için.pre-push— uzak depoya göndermeden önce. Biraz daha yavaş kontroller buraya sığar.
Sıralama önemli: her kontrolü pre-commit'e yığmak en yaygın hata. Commit, günde onlarca kez yapılan bir işlem; oraya koyduğunuz her saniye günde dakikalara dönüşüyor.
Zaman bütçesi
Pratikte işleyen dağılım şu:
| Aşama | Bütçe | Uygun kontroller |
|---|---|---|
| pre-commit | < 2 saniye | Biçimlendirme, sözdizimi, sır taraması |
| commit-msg | anlık | Mesaj biçimi |
| pre-push | < 30 saniye | Hızlı birim testleri, statik analiz |
| CI sunucusu | dakikalar | Tüm testler, güvenlik taraması, derleme |
Bu bütçeyi aşan her kontrol, geliştiricileri --no-verify kullanmaya iter. Kapının atlanabilir olması sorun değil; düzenli olarak atlanıyor olması sorundur.
Ekipte paylaşılabilir kurulum
.git/hooks klasörü depoya dâhil değildir; oraya yazdığınız betik yalnızca sizde çalışır. Çözüm, hook'ları depoda izlenen bir klasöre koyup Git'i oraya yönlendirmek:
mkdir -p .githooks
git config core.hooksPath .githooks
chmod +x .githooks/*Ayar komutunu kurulum betiğinize veya README'nin ilk adımına koyun. Böylece depoyu klonlayan herkes aynı kapıyı kuruyor ve hook'lar sürüm kontrolüyle birlikte gelişiyor.
İşe yarayan bir pre-commit
Aşağıdaki betik dört şeyi kontrol ediyor ve yalnızca hazırlanmış dosyalara bakıyor — bu, süreyi saniyelerde tutan asıl ayrıntı:
#!/bin/sh
# .githooks/pre-commit
DOSYALAR=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$')
[ -z "$DOSYALAR" ] && exit 0
# 1) Sözdizimi
for f in $DOSYALAR; do
php -l "$f" > /dev/null || { echo "✗ Sözdizimi hatası: $f"; exit 1; }
done
# 2) Unutulmuş hata ayıklama satırları
if git diff --cached -U0 -- $DOSYALAR | grep -nE '^\+.*(var_dump|dd\(|console\.log)'; then
echo "✗ Hata ayıklama satırı kalmış."
exit 1
fi
# 3) Sır sızıntısı (kaba ama etkili)
if git diff --cached -U0 -- $DOSYALAR | grep -nE '^\+.*(AKIA[0-9A-Z]{16}|-----BEGIN [A-Z ]*PRIVATE KEY)'; then
echo "✗ Kaynak koda anahtar eklenmiş görünüyor."
exit 1
fi
# 4) Biçimlendirme (düzeltip yeniden hazırla)
vendor/bin/php-cs-fixer fix --quiet $DOSYALAR 2>/dev/null && git add $DOSYALAR
exit 0Üçüncü kontrol, tek başına bu kurulumu haklı çıkarıyor. Depoya girmiş bir anahtar, sonradan silinse bile geçmişte kalır; tek çözüm anahtarı iptal edip yenilemektir. Sırların doğru yeri konusunda .env dosyasından sır kasasına geçiş yazısına bakabilirsiniz.
Commit mesajı denetimi
Mesaj biçimini standartlaştırmak, sürüm notlarını otomatik üretebilmenin ön koşulu:
#!/bin/sh
# .githooks/commit-msg
DESEN='^(feat|fix|docs|refactor|test|chore)(\([a-z0-9-]+\))?: .{10,}'
grep -qE "$DESEN" "$1" || {
echo "✗ Mesaj biçimi: tip(kapsam): en az 10 karakter açıklama"
exit 1
}Bu kuralı koymadan önce ekiple konuşun; tek taraflı dayatılan biçim kuralları genellikle ilk haftadan sonra atlanmaya başlıyor. İyi bir commit mesajının neden önemli olduğu konusunda Git ile çalışma yazısında ayrıntı var.
pre-push: testin doğru yeri
Testleri commit'e değil push'a bağlayın. Geliştirici gün içinde onlarca commit atar ama günde birkaç kez push eder; testin oraya taşınması hem bütçeye uyuyor hem de bozuk kodun uzak depoya çıkmasını engelliyor.
#!/bin/sh
# .githooks/pre-push — yalnızca hızlı takım
vendor/bin/phpunit --testsuite=unit --stop-on-failure || {
echo "✗ Birim testleri başarısız. Göndermeden önce düzeltin."
exit 1
}Hızlı takımı gerçekten hızlı tutun. Veritabanına giden testler bu aşamaya değil CI'ya ait; ayrımın nasıl kurulacağı için hangi testi ne zaman yazmalı yazısı yardımcı olur.
Hook'lar bir güvenlik sınırı değildir. Yerel makinede çalışırlar, kapatılabilirler ve depoyu klonlayan biri hiç kurmayabilir. Bir kontrolün kesinlikle uygulanması gerekiyorsa yeri sunucudur: birleştirmeyi engelleyen zorunlu CI adımı olarak tanımlayın. Hook, hatayı erken göstermek içindir; garanti etmek için değil.
Kademeli devreye alma
Tüm kuralları bir gecede zorunlu yapmak, mevcut kod tabanında yüzlerce ihlalle karşılaşmak demek. Daha az sancılı yol: kuralları önce yalnızca değişen dosyalara uygulayın. Kod tabanı zamanla, dokunuldukça temizlenir; kimse "43 dosyada biçim düzeltmesi" başlıklı bir değişiklik incelemek zorunda kalmaz.
Sonuç
Git hook kalite kapısı, ekibe getirdiği yükün çok üstünde bir getiri sağlıyor: kurulumu bir öğleden sonra, bakımı neredeyse sıfır. Kritik olan iki şey var — kontrolleri doğru aşamaya yerleştirmek ve commit anını iki saniyenin altında tutmak. Bu ikisi sağlandığında hook'lar görünmez hâle geliyor; yalnızca gerçekten bir hata olduğunda konuşuyorlar. Dallanma tarafını da düzenlemek isterseniz trunk-based mi Git Flow mu yazısına göz atın.
Hook türlerinin tam listesi: Git — githooks belgeleri.
Sık sorulan sorular
Git hook kalite kapısı ekipte nasıl paylaşılır?
Varsayılan olarak .git/hooks klasörü depoya dâhil değildir, yani hook'lar kopyalanmaz. Çözüm, hook betiklerini depoda izlenen bir klasörde tutup core.hooksPath ayarını oraya yönlendirmek. Böylece klonlayan herkes tek komutla aynı kapıyı kurmuş oluyor.
Hook'lar geliştiriciyi yavaşlatmaz mı?
Yanlış kurulursa yavaşlatır. Pratik sınır şu: commit anındaki kontroller iki saniyeyi geçmemeli. Testleri pre-commit'e koyan ekipler kısa sürede --no-verify ile hook'u atlamaya başlıyor, yani kapı fiilen kapanıyor. Yavaş kontroller pre-push ve CI aşamalarına ait.
Sadece değişen dosyalar kontrol edilebilir mi?
Evet ve edilmelidir. Tüm projeyi her commit'te taramak büyük depolarda dakikalar sürer. git diff --cached ile yalnızca hazırlanmış dosyaları alıp kontrolü onlara uygulamak, süreyi saniyelere indiriyor.
Hook varken CI'ya hâlâ ihtiyaç var mı?
Kesinlikle. Hook'lar yerel makinede çalışır ve atlanabilir; güvenlik sınırı değil, kolaylık aracıdırlar. Zorunlu kontroller sunucuda, birleştirmeyi engelleyecek şekilde tanımlanmalı. İkisi birbirinin yerine değil, tamamlayıcısıdır.
Yazan
Çılgın Yazılım
Ben Evren Çılgın; yazılım geliştirme, web teknolojileri ve sistem tasarımı alanlarında uzmanlaşmış bir geliştiriciyim. Uzun yıllardır hem frontend hem de backend tarafında üretken, ölçeklenebilir ve kullanıcı dostu çözümler üretiyorum.
Bu konuda bir projeniz mi var?
İhtiyacınızı birkaç cümleyle anlatın; uygun yaklaşımı birlikte belirleyelim.
İlgili yazılar
Yorumlar
Henüz yorum yok. Sorunuzu ya da deneyiminizi ilk siz yazın.
Yorum yazın
Yorumunuz onaylandıktan sonra yayınlanır. Ekibimiz gerekirse konuyla ilgili bir yanıt da paylaşır.
