Commit Disiplini
Atomik, okunur ve anlam taşıyan git commit'leri yazmayı öğreten skill — conventional commits + "neden" disiplini + atomiklik kuralları + staging hijyeni.
İçerik
Commit Disiplini
Claude Code'a commit yazarken uygulanacak disiplinleri öğretir. ~/.claude/skills/commit-disiplini/SKILL.md olarak yerleştirildiğinde veya /skill commit-disiplini ile çağrıldığında etkinleşir.
Ne zaman aktif olur
git commityapılacakken- Kullanıcı "bunu commit et" dediğinde
- Büyük değişikliği commit'lere bölerken
- Commit mesajı revize edilirken (rebase -i, reword)
Çekirdek prensipler
1. Atomiklik — bir commit, bir niyet
Bir commit tek bir niyeti temsil eder. İki farklı iş (refactor + yeni feature, bug fix + dokümantasyon yenilemesi) aynı commit'e girmez.
Böyle bir durumla karşılaştığında staging'i parçala:
git add -p <file> # hunk hunk seç
git stash -p # geri alacağın hunk'ları stash'le
git restore --staged <file> # staged'dan çıkar
2. "Neden" > "ne"
git diff zaten ne değiştiğini gösterir. Commit mesajı neden değiştiğini söyler.
Kötü: Update auth.ts — diff zaten bunu söylüyor.
İyi: fix(auth): reject expired tokens before DB lookup to close timing side-channel
3. Staging hijyeni
git add -A/git add .: yasak..env, credentials, log dosyaları, node_modules bölümü kapıp commit'e girer.- Dosyaları isimle stage et:
git add src/foo.ts src/bar.ts - Karışık değişiklik varsa
git add -pile hunk seç - Commit'ten önce her zaman
git status+git diff --stagedile kontrol
4. Emir kipi
Commit başlığı "bu commit uygulanırsa X yapar" şeklinde okunur. Geçmiş zaman yasak.
| ❌ Kötü | ✅ İyi |
|---|---|
added login page |
add login page |
fixes crash on submit |
fix crash on submit |
refactored auth module |
refactor auth module |
Mesaj formatı (Conventional Commits + why)
<type>(<scope>): <kısa özet — niyeti tarif et>
<opsiyonel gövde — neden bu yaklaşım, trade-off, referans>
<opsiyonel footer — breaking change, issue ref, co-author>
Type'lar
| Type | Kullanım |
|---|---|
feat |
Yeni kullanıcıya görünen özellik |
fix |
Bug fix |
refactor |
Davranış değişmez, yapı değişir |
perf |
Performans iyileştirmesi (davranış değişmez) |
test |
Test ekleme/düzeltme (kod değişmedi) |
docs |
Dokümantasyon |
chore |
Rutin iş (bağımlılık bump, config) |
build |
Build sistemi / bundler değişiklikleri |
ci |
CI/CD pipeline |
revert |
Önceki commit'i geri al |
style |
Whitespace/format (tercih: tool ile otomatize) |
Scope
Opsiyonel ama faydalı. Dosya değil, alan belirtir: (auth), (api), (ui/button), (db), (deploy).
Başlık kuralları
- 72 karakteri geçme (bazı araçlar 50-72 pencereli görüntüler)
- Büyük harfle başlama, nokta ile bitirme yok
- İmperative mood ("add", "fix", "remove")
- İşi, değişikliği değil
Gövde kuralları
- Başlıktan sonra bir boş satır
- 72 karakterde satır başı
- Nedeni anlat — "şu eski davranış vardı, şu soruna yol açıyordu, yeni yaklaşım şöyle çözüyor"
- İlgili issue / PR / ticket link'i:
Closes #123,Refs PROJ-456
Footer
BREAKING CHANGE: <ne değişti, migration ne>— major version triggerCo-Authored-By: Name <email>Signed-off-by:— DCO gerektiren projeler
İyi örnekler
fix(auth): reject expired tokens before DB lookup
Token hash'i doğrulamadan önce exp claim'i kontrol ediliyor artık.
Eskiden exp check DB lookup'tan sonraydı, süresi geçmiş token'lar
bile sorgu yapıp DoS amplification imkanı yaratıyordu.
Measurement: p95 invalid-token latency 120ms → 3ms.
Closes #842
refactor(db): extract query builders into repository classes
Route handler'ların içindeki raw SQL'ler test edilebilir değildi.
Her tablo için *Repo sınıfı, DI ile inject ediliyor. Davranış
değişmedi, sadece topoloji.
Follow-up: #850 (diğer handler'ları migrate et).
perf(list): virtualize product grid above 200 items
React TanStack Virtual eklendi. 500 öğe renderında FPS 18 → 58,
memory 210MB → 85MB.
feat(search): add fuzzy matching for Turkish inflections
Lunr yerine fuse.js + custom Turkish tokenizer. "araba"
aramasında "arabaların", "arabama" gibi ekli sonuçlar da döner.
BREAKING CHANGE: search() API iç mekanikleri değişti, sonuç
şekli aynı.
Refs #720
Kötü örnekler
fixed bug
Hangi bug, niçin, ne değişti — hiçbiri yok.
WIP
Commit atomik değil, merge'e hazır değil. Rebase edilmeden merge'e girmemeli.
updated files
Hangi dosya, neden. Diff zaten dosyaları söyler.
asdf
Gerçek bir commit değil. Prod'a kadar gider.
feat: stuff
Büyük ihtimalle birden çok niyet karışmış. Böl.
Büyük değişikliği bölme
Yazdığın 20-dosyalık feature tek commit olmayacak. Böl:
1. refactor(db): extract user repository layer (davranış değişmez)
2. feat(db): add email_verified_at column (schema + migration)
3. feat(auth): send verification email on signup (yeni akış)
4. feat(auth): require email_verified for checkout (kısıt)
5. docs(auth): document email verification flow (readme + ADR)
Her commit tek başına build'li, test'li, review edilebilir. Commit N'de feature yarım kalmaz.
Pre-commit hook ile ilişki
- Hook fail ederse commit gerçekleşmemiştir.
--amendkullanma — önceki commit'i bozarsın. - Hook'u atlamak (
--no-verify): kullanıcı explicit istemedikçe ASLA. Hook güvenlik/kalite guard'ı. - Hook yavaşsa rework et, bypass etme.
--amend ne zaman olur?
Sadece son commit senin ve henüz push etmediysen:
- Typo düzeltme (dosya eklemeyi unutmadınsa)
- Commit mesajını düzenlemek
Push sonrası amend: co-worker'ların local branch'leri bozulur. Yapma. Yeni commit at ya da revert + re-commit.
Revert vs Reset
| Durum | Kullan |
|---|---|
| Push edilmiş commit'i geri al | git revert <sha> — history korunur |
| Henüz push edilmemiş local commit | git reset HEAD~1 (mix/soft) — geri alınıp düzenlenir |
| Branch'i "temizlemek" için force push | Dikkat — shared branch'te asla |
Doğrulama (commit'ten önce checklist)
-
git statusile staging'de olmaması gerekenler yok -
git diff --stagedile ekleneceği yazdığımla eşleşiyor - Mesaj 72 karakter ≤, imperative mood, neden anlatıyor
- Atomic: tek niyet, karışık iş yok
- Hook'lar yeşil (atlanmadı)
-
.env, secret, kaldırılmış dosyalar sızmadı - Issue/PR referansı varsa eklendi
- Breaking change varsa footer'da
BREAKING CHANGE:
Yasaklar özet
--amendpre-commit hook başarısız olduktan sonra — ASLA--no-verify— explicit kullanıcı isteği olmadan ASLAgit add -A/git add .— dosya dosya ekle- "WIP", "asdf", "fix" gibi anlamsız mesaj
- Push edilmiş commit'i amend etmek
- Mesajın başlığında 72 karakter sınırını aşmak
- Nokta ile biten başlık
- Geçmiş zaman (fixed, added) — imperative kullan