Release Branch Yönetimi ve Hotfix Süreci: Eksiksiz Git Rehberi
Geçen ay bir müşterimizde production’a yanlış branch’ten deploy yapıldı. Sonuç? Yarım saatlik kesinti, birkaç saatlik panik ve epey bir postmortem toplantısı. Oysa düzgün bir release branch stratejisi ve hotfix süreci olsaydı, bu kaostan tamamen kaçınılabilirdi. Bu yazıda hem release branch yönetimini hem de acil durumlarda hotfix sürecini gerçek dünya pratikleriyle ele alacağım.
Release Branch Nedir ve Neden Önemlidir
Birçok ekip “main’e merge et, tag’le, deploy et” mantığıyla çalışır. Küçük projeler için bu yeterli olabilir, ama orta ve büyük ölçekli sistemlerde bu yaklaşım er ya da geç sizi sıkıştırır. Release branch’leri, bir sonraki sürümü production’a çıkmadan önce izole bir ortamda stabilize etmenizi sağlar.
Temel mantık şu: develop branch’inde feature geliştirmesi sürerken, belirli bir noktada release adayını ayırırsınız. Bu noktadan sonra o release branch’ine sadece bug fix girer, yeni feature girmez. Böylece hem release süreci kontrol altında kalır hem de develop branch’indeki geliştirmeler duraksatılmaz.
Gitflow bu konuda en yaygın referans model. Ama Gitflow’u olduğu gibi uygulamak yerine, ekibinizin ihtiyaçlarına göre şekillendirmek çok daha sağlıklı sonuç verir.
Release Branch Oluşturma
Pratikte release branch’i genellikle sprint sonu veya feature freeze noktasında oluşturulur. İsimlendirme konusunda tutarlı olmak kritik önem taşır.
# develop branch'inden release branch'i oluşturmak
git checkout develop
git pull origin develop
git checkout -b release/1.4.0
# Remote'a push et
git push -u origin release/1.4.0
Semantic versioning kullanıyorsanız branch adında da aynı versiyonu yansıtın. release/1.4.0, release/v1.4.0 veya release/2024-Q1 gibi formatlar sık kullanılır. Ne seçerseniz seçin, tüm ekip aynı konvansiyonu kullanmalı.
Branch oluşturduktan sonra ilk commit genellikle versiyon numarasını güncellemek olur:
# Versiyon dosyasını güncelle (örnek: Python projesi)
echo "1.4.0" > VERSION
git add VERSION
git commit -m "chore: bump version to 1.4.0"
git push origin release/1.4.0
Release Branch’e Nelerin Gireceğini Tanımlamak
Bu noktada ekiple açık bir anlaşma olması gerekiyor. Release branch açıldıktan sonra kabul edilen değişiklikler:
- Kritik bug fix’ler (test sürecinde bulunanlar)
- Dokümantasyon güncellemeleri
- Konfigürasyon düzeltmeleri
- Çeviri/locale düzeltmeleri
Kabul edilmeyenler:
- Yeni özellikler
- Refactoring
- Performans iyileştirmeleri (kritik olmayan)
- Deneysel değişiklikler
Bu kuralı CI/CD pipeline’ınızda da enforce edebilirsiniz. Branch protection rules ile release branch’lerine doğrudan push’u engelleyin, sadece PR üzerinden merge’e izin verin.
Release Sürecinde Branch Yönetimi
Release branch hayatta olduğu sürece hem develop hem de release branch’ine paralel çalışılır. Develop’ta yapılan ve release için gerekli olan fix’ler cherry-pick ile alınabilir, ya da release’de yapılan fix’ler develop’a backport edilir.
# Develop'ta yapılan bir fix'i release branch'ine taşımak
git checkout develop
git log --oneline -10
# İlgili commit hash'ini bulduktan sonra
git checkout release/1.4.0
git cherry-pick a3f2b1c
git push origin release/1.4.0
Cherry-pick kullanırken dikkatli olun. Özellikle bağımlı commit’ler varsa veya dosya çakışmaları söz konusuysa, cherry-pick sonrası mutlaka test edin.
Merge Conflict Yönetimi
Uzun süren release süreçlerinde kaçınılmaz olarak conflict çıkar. Bunu minimize etmenin yolu, release branch’inin ömrünü kısa tutmaktır. İki haftadan uzun süren release dönemleri gereksiz karmaşıklık yaratır.
# Release branch'ini develop ile güncel tutmak (gerektiğinde)
git checkout release/1.4.0
git merge develop --no-ff -m "merge: sync develop changes into release/1.4.0"
# Conflict durumunda
git status
# Conflict olan dosyaları düzenle
git add .
git commit -m "fix: resolve merge conflicts from develop"
Ama şunu da söyleyeyim, develop’u release’e merge etmek her zaman doğru değil. Özellikle develop’ta henüz olgunlaşmamış feature’lar varsa, bu merge işlemi sizi daha büyük bir kaosa sürükleyebilir. Bu kararı ekip olarak bilinçli verin.
Release Tamamlama
QA onayı alındığında ve release production’a çıkmaya hazır olduğunda, release branch’ini hem main hem de develop‘a merge etmek gerekir.
# main'e merge et
git checkout main
git pull origin main
git merge --no-ff release/1.4.0 -m "release: merge release/1.4.0 into main"
git tag -a v1.4.0 -m "Release version 1.4.0"
git push origin main
git push origin v1.4.0
# develop'a da merge et (release sırasında yapılan fix'lerin geri taşınması)
git checkout develop
git pull origin develop
git merge --no-ff release/1.4.0 -m "release: merge release/1.4.0 back into develop"
git push origin develop
# Release branch'ini sil (opsiyonel ama önerilir)
git branch -d release/1.4.0
git push origin --delete release/1.4.0
--no-ff flag’ini kullanmak önemli. Fast-forward merge yaptığınızda branch’in izini kaybedersiniz. Non-fast-forward merge ile release branch’inin git history’de görünür kalmasını sağlarsınız. Bu, ileride hangi commit’lerin hangi release’e girdiğini anlamak için değerlidir.
Tag oluşturmayı da ihmal etmeyin. Tag’ler olmadan versiyonlar arasında karşılaştırma yapmak, rollback senaryolarını yönetmek çok zorlaşır.
Hotfix Süreci: En Kritik Senaryo
Şimdi asıl konuya geliyoruz. Gece 02:00, production’da kritik bir bug var, müşteriler etkileniyor. Ne yapacaksınız?
Hotfix süreci, production’daki acil sorunları hızlıca çözmek için main branch üzerinden doğrudan çalışmayı gerektirir. Develop’u bypass edersiniz çünkü develop’ta henüz test edilmemiş değişiklikler olabilir.
# Main branch'ten hotfix branch'i aç
git checkout main
git pull origin main
git checkout -b hotfix/1.4.1
# Fix'i uygula
# ... kod değişiklikleri ...
git add .
git commit -m "fix: kritik ödeme hatası düzeltildi - null pointer exception"
git push -u origin hotfix/1.4.1
Hotfix Branch Kuralları
Hotfix branch’inde şunlara dikkat edin:
- Tek bir sorunu çözün: Hotfix, acil durumu düzeltmek içindir. Fırsatçı olup başka şeyler de yapmaya kalkmayın.
- Mümkün olan en minimal değişikliği yapın: Az değişiklik, az risk demektir.
- Test yazın: Acele olsa bile, o bug’ı kapsayan en azından bir test ekleyin. Aynı bug’ın geri dönmemesi için.
- Commit mesajı açıklayıcı olsun: Postmortem’de o commit’e bakacak insanlar için context verin.
Hotfix’i Hızlıca Test Etmek
CI pipeline’ınız varsa, hotfix branch push edildiğinde otomatik testler çalışmalı. Ama bazı durumlarda CI yavaş kalabilir. Bu durumda lokal hızlı test:
# Hotfix branch'inde lokal test
cd /path/to/project
git stash # Varsa bekleyen değişiklikler
git checkout hotfix/1.4.1
# Testleri çalıştır
npm test -- --grep "payment" # Sadece ilgili testler
# veya
pytest tests/test_payment.py -v
# Docker ile izole test ortamı (varsa)
docker-compose -f docker-compose.test.yml up --build --exit-code-from app
Hotfix’i Deploy Etmek
Test geçtikten sonra hotfix’i hem main’e hem de develop’a merge etmeniz gerekiyor:
# Versiyon numarasını güncelle
echo "1.4.1" > VERSION
git add VERSION
git commit -m "chore: bump version to 1.4.1"
# Main'e merge et ve tag'le
git checkout main
git pull origin main
git merge --no-ff hotfix/1.4.1 -m "hotfix: merge hotfix/1.4.1 into main"
git tag -a v1.4.1 -m "Hotfix: kritik ödeme hatası düzeltildi"
git push origin main
git push origin v1.4.1
# Develop'a da merge et
git checkout develop
git pull origin develop
git merge --no-ff hotfix/1.4.1 -m "hotfix: merge hotfix/1.4.1 back into develop"
git push origin develop
# Hotfix branch'ini temizle
git branch -d hotfix/1.4.1
git push origin --delete hotfix/1.4.1
Aktif Release Branch Varsa Ne Olur?
İşte bu senaryo sık karşılaşılan ve genellikle gözden kaçan durum. Hotfix yaparken aynı zamanda aktif bir release branch’i varsa (1.5.0 için hazırlık yapılıyor diyelim), hotfix’i o release branch’ine de taşımanız gerekebilir.
# Hotfix'i aktif release branch'ine de uygula
git checkout release/1.5.0
git pull origin release/1.5.0
git cherry-pick <hotfix_commit_hash>
git push origin release/1.5.0
Ya da release branch’i develop’a merge edileceğinde bu fix zaten gelecekse, cherry-pick gerekmeyebilir. Bu kararı branch’lerin durumuna göre verin. Ama karışıklık yaşamamak için, hotfix sonrası ekiple kısa bir sync toplantısı yapmak iyi alışkanlıktır.
Otomasyon ve Tooling
Manuel adımlar hata üretir, özellikle gece yarısı panik ortamında. Bu yüzden release ve hotfix süreçlerini mümkün olduğunca otomatize etmek gerekiyor.
Basit bir release script örneği:
#!/bin/bash
# release-start.sh
VERSION=$1
if [ -z "$VERSION" ]; then
echo "Kullanim: ./release-start.sh <versiyon>"
echo "Ornek: ./release-start.sh 1.4.0"
exit 1
fi
BRANCH_NAME="release/$VERSION"
echo "Release branch olusturuluyor: $BRANCH_NAME"
git checkout develop
git pull origin develop
if git show-ref --quiet refs/heads/$BRANCH_NAME; then
echo "HATA: $BRANCH_NAME branch'i zaten mevcut!"
exit 1
fi
git checkout -b $BRANCH_NAME
echo "$VERSION" > VERSION
git add VERSION
git commit -m "chore: bump version to $VERSION"
git push -u origin $BRANCH_NAME
echo "Release branch hazir: $BRANCH_NAME"
echo "Simdi QA surecini baslatin."
Bu script’i ekip içinde paylaşın, herkesin aynı adımları takip etmesini sağlayın. Bash yerine Python veya başka bir dille de yazabilirsiniz, önemli olan tutarlılık.
GitHub Actions ile release oluşturulduğunda otomatik bildirim almak da kolaydır:
# .github/workflows/release-notify.yml icin ornek adim
# Release branch'e push yapildiginda Slack bildirimi
- name: Notify Slack
if: startsWith(github.ref, 'refs/heads/release/')
run: |
curl -X POST -H 'Content-type: application/json'
--data '{"text":"Yeni release branch olusturuldu: '"$GITHUB_REF_NAME"'"}'
${{ secrets.SLACK_WEBHOOK_URL }}
Sık Yapılan Hatalar ve Kaçınma Yolları
Yıllar içinde gördüğüm en yaygın hataları sıralayayım:
- Release branch’ini çok geç oluşturmak: Feature freeze’den sonra beklememek gerekir. Geç oluşturulan release branch, develop’tan uzaklaşır ve merge sıkıntıları başlar.
- Hotfix’i sadece main’e merge etmek: En yaygın hata bu. Develop’u unutursanız, bir sonraki release’te aynı bug’ı tekrar görürsünüz.
- Tag atmayı unutmak: Tagsiz deployment history’si bir süre sonra anlamsız hale gelir. Tag atma işlemini CI/CD pipeline’ına bağlayın, insanın aklına güvenmeyin.
- Çok uzun süren release branch’leri: İki haftadan uzun release süreçleri, ekibi yorar ve branch divergence problemleri doğurur.
- Hotfix’e birden fazla fix sıkıştırmak: “Zaten açmışken şunu da düzeltelim” tuzağına düşmeyin. Her hotfix, tek bir problemi çözmelidir.
Branch Protection ve Governance
Teknik süreçlerin yanında, kurumsal kural setleri de önemli. GitHub, GitLab veya Bitbucket kullanıyorsanız branch protection rules’u aktive edin.
Önerilen kurallar:
- main ve develop branch’leri: Doğrudan push yasak, sadece PR üzerinden merge
- Release branch’leri: En az 1 reviewer onayı zorunlu, CI testleri geçmeden merge yapılamaz
- Hotfix branch’leri: Acil durumda hızlı approve için belirli kişilere bypass yetkisi verilebilir, ama bu yetkiyi loglayin
Bütün bu kuralları ekiple yazılı hale getirin. “Git kullanım kılavuzu” veya “Branching strategy” adıyla bir doküman hazırlayın. Bu doküman, yeni ekip üyelerinin onboarding sürecinde de hayat kurtarır.
Gerçek Dünya Notu: Küçük Ekipler İçin
Gitflow’un tüm bu katmanları, beş kişilik bir startup ekibine fazla gelebilir. Bu durumda basitleştirilmiş bir yaklaşım işe yarar:
- main: Her zaman production-ready
- develop: Aktif geliştirme
- release/x.y.z: Sadece stabilizasyon için, kısa ömürlü
- hotfix/x.y.z: Acil düzeltmeler
Feature branch’leri opsiyonel. Küçük değişiklikler doğrudan develop’a gidebilir. Önemli olan hotfix ve release disiplinini korumak.
Sonuç
Release branch yönetimi ve hotfix süreci, Git’in teknik özelliklerinden çok bir ekip kültürü ve disiplin meselesi. En iyi araçlara ve en detaylı dokümanlara sahip olsanız bile, ekip bu süreci benimsemezse her şey kağıt üzerinde kalır.
Öncelik sırasına göre yapmanız gerekenler şöyle özetlenebilir: İlk olarak branch stratejinizi yazılı hale getirin ve ekiple mutabık kalın. Sonra tekrarlayan adımları script’lerle otomatize edin. Ardından branch protection rules’u aktive edin. Son olarak her release ve hotfix sonrası kısa bir retrospektif yapın, sürecinizi sürekli iyileştirin.
Gece yarısı production’da bir şeyler patladığında, o anda doğru kararlar vermek zordur. Ama süreci daha önceden oturtmuşsanız, “şimdi ne yapacağız?” sorusunun cevabı hazır olur. Panik yerine execution moduna geçersiniz. Bence bu, iyi bir release yönetiminin en değerli yanı budur.
