GitHub Flow vs Git Flow: Hangi Dal Stratejisini Seçmeli?
Yıllarca hem GitHub Flow hem de Git Flow kullanan biri olarak şunu rahatlıkla söyleyebilirim: Bu iki strateji arasındaki seçim, salt teknik bir tercih değil, aynı zamanda ekibinizin çalışma kültürünü ve ürününüzün yayınlanma ritmine dair bir karar. Hangisinin “daha iyi” olduğu sorusunun cevabı yok, ama hangisinin “sizin için daha uygun” olduğunun cevabı kesinlikle var.
Git Flow Nedir, Neden Ortaya Çıktı?
Git Flow, 2010 yılında Vincent Driessen’ın bir blog yazısıyla dünyaya tanıttığı bir branch stratejisidir. O dönemde yazılım dünyası çok farklıydı: Aylık veya üç aylık release döngüleri, büyük versiyon geçişleri ve paralel olarak birden fazla versiyonun bakımını yapmak zorunda kalan ekipler vardı. Git Flow tam olarak bu ihtiyaca yanıt verdi.
Temel fikir şu: Her şeyin bir yeri var ve her şey yerli yerinde olmalı.
Git Flow’un iskeletini oluşturan branch yapısı:
- main (master): Sadece production’a çıkan, etiketlenmiş kodlar buradadır
- develop: Bir sonraki release için hazırlanan ana entegrasyon branch’i
- feature/*: Yeni özellik geliştirme branch’leri, develop’tan açılır
- release/*: Release hazırlık branch’leri, develop’tan açılır
- hotfix/*: Production’daki kritik hataların düzeltildiği branch’ler, main’den açılır
# Git Flow başlatma (git-flow eklentisi ile)
git flow init
# Yeni feature branch açma
git flow feature start kullanici-profil-sayfasi
# Feature tamamlandığında develop'a merge etme
git flow feature finish kullanici-profil-sayfasi
# Release branch açma
git flow release start 2.4.0
# Release'i bitirme (hem main hem develop'a merge eder)
git flow release finish 2.4.0
Bu komutları elle de yapabilirsiniz elbette, git-flow eklentisi sadece bir kolaylık. Önemli olan sürecin kendisi.
GitHub Flow Nedir?
GitHub Flow, adından da anlaşılacağı üzere GitHub’ın kendi iç süreçlerinden doğdu. GitHub ekibi günde onlarca kez production’a deploy ederken Git Flow’un karmaşıklığından bunalmıştı. 2011’de Scott Chacon bu stratejiyi belgeledi ve son derece minimalist bir yaklaşım ortaya çıktı.
Kurallar inanılmaz derecede basit:
- main her zaman deployable’dır, yani production’a çıkmaya hazır
- Her yeni iş için main’den feature branch açarsın
- Hazır olduğunda pull request açarsın
- Review sonrası main’e merge edilir ve hemen deploy edilir
# GitHub Flow ile yeni bir özellik başlatma
git checkout main
git pull origin main
git checkout -b feature/odeme-sistemi-entegrasyonu
# Geliştirme yapılıyor...
git add .
git commit -m "Stripe ödeme entegrasyonu eklendi"
git push origin feature/odeme-sistemi-entegrasyonu
# Pull request açılır, review yapılır, main'e merge edilir
# Merge sonrası otomatik deploy tetiklenir
İşte bu kadar. İki branch, bir kural: main her zaman çalışır.
Gerçek Hayatta Git Flow: Bir E-Ticaret Projesi Senaryosu
Bir e-ticaret platformunda çalıştığınızı düşünün. Ekibinizde 8 geliştirici var, her ay belirli tarihlerinde yeni sürüm çıkarıyorsunuz ve müşterileriniz arasında on-premise kurulum yapılan kurumsal firmalar da bulunuyor. Bu senaryo Git Flow’un tam olarak parladığı yerdir.
Diyelim ki Kasım ayının başında “2.5.0” sürümü için çalışmaya başladınız:
# Develop branch'ten feature açılıyor
git checkout develop
git pull origin develop
git checkout -b feature/toplu-siparis-modulu
# 2 hafta boyunca geliştirme...
git add src/orders/bulk_order.py
git commit -m "feat: toplu sipariş modülü temel yapısı"
git commit -m "feat: CSV import özelliği eklendi"
git commit -m "test: toplu sipariş unit testleri"
# Feature tamamlandı, develop'a merge
git checkout develop
git merge --no-ff feature/toplu-siparis-modulu
git branch -d feature/toplu-siparis-modulu
git push origin develop
Kasım ortasında release hazırlığı başlıyor:
# Release branch açılıyor
git checkout develop
git checkout -b release/2.5.0
# Sadece bug fix'ler yapılıyor, yeni özellik eklenmez
git commit -m "fix: toplu sipariş CSV parsing hatası düzeltildi"
git commit -m "chore: versiyon numarası 2.5.0 olarak güncellendi"
# QA onayladı, release tamamlanıyor
git checkout main
git merge --no-ff release/2.5.0
git tag -a v2.5.0 -m "Release 2.5.0"
git checkout develop
git merge --no-ff release/2.5.0
git branch -d release/2.5.0
git push origin main develop --tags
Kasım sonunda production’da kritik bir bug bulundu:
# Hotfix main'den açılır, develop'tan değil!
git checkout main
git checkout -b hotfix/kritik-odeme-hatasi
git commit -m "fix: ödeme sonrası stok güncellemesi eksikliği giderildi"
# Hem main hem develop'a uygulanır
git checkout main
git merge --no-ff hotfix/kritik-odeme-hatasi
git tag -a v2.5.1 -m "Hotfix: kritik ödeme hatası"
git checkout develop
git merge --no-ff hotfix/kritik-odeme-hatasi
git branch -d hotfix/kritik-odeme-hatasi
Bu akışın güzelliği şu: Herkes ne zaman ne yapacağını biliyor. Release tarihleri önceden bellidir, QA süreci netlidir ve birden fazla versiyon aynı anda bakımda olabilir.
Gerçek Hayatta GitHub Flow: Bir SaaS Startup Senaryosu
Şimdi başka bir düşünce deneyi yapalım. 4 kişilik bir startup’ta çalışıyorsunuz, bir SaaS ürün geliştiriyorsunuz ve her tamamlanan özellik “neden bekleyelim ki?” mantığıyla hemen canlıya alınıyor. Müşteriler her hafta yeni şeyler görmeyi bekliyor, A/B testleri sık sık yapılıyor. Bu ortamda Git Flow’u uygulamaya kalkmak, bisikletle Türkiye’yi dolaşmak için GPS yerine pusula kullanmaya benzer.
# Sabah daily'de bug report geldi
git checkout main
git pull origin main
git checkout -b fix/anasayfa-yavaslama-sorunu
# Profiling yapıldı, sorun bulundu
git add src/components/Homepage.jsx
git commit -m "fix: anasayfa N+1 query sorunu çözüldü, sayfa yükü %60 azaldı"
# Push ve PR
git push origin fix/anasayfa-yavaslama-sorunu
# GitHub'da PR açılır, takım arkadaşı review eder
# Onay geldi, squash and merge
# CI/CD otomatik deploy etti, öğleden önce production'da
Aynı gün başka bir geliştirici farklı bir özellik üzerinde çalışıyor:
git checkout main
git checkout -b feature/dashboard-export-excel
# Geliştirme süreci
git commit -m "feat: dashboard verileri Excel'e aktarma özelliği"
git commit -m "test: export edge case'leri test edildi"
git push origin feature/dashboard-export-excel
# PR açılır, 2 cycle review, küçük düzeltmeler yapılır
# Merge ve otomatik deploy
Bu ortamda iki geliştirici aynı anda bambaşka şeyler üzerinde çalışabiliyor, birbirlerini bloklamıyor. Main her an deployable olduğu için “acil bir şey çıkarabilir miyiz?” diye sormanıza gerek kalmıyor.
Branch Temizliği ve Disiplin
İki stratejide de zamanla ihmal edilirse branch kirliliği baş ağrısına dönüşür. GitHub Flow’da özellikle dikkatli olun:
# Merge edilmiş remote branch'leri temizleme
git fetch --prune
git branch -r | grep -v '->' | while read remote; do
git branch --track "${remote#origin/}" "$remote" 2>/dev/null
done
# Yerel olarak merge edilmiş branch'leri listele
git branch --merged main | grep -v "main"
# Toplu silme (dikkatli kullanın!)
git branch --merged main | grep -v "main" | xargs git branch -d
# Remote'ta merge edilmiş branch'leri sil
git push origin --delete $(git branch -r --merged origin/main |
grep -v "main" | sed 's/origin///')
Git Flow kullanıyorsanız düzenli aralıklarla develop branch’ini kontrol edin:
# Develop'a merge edilmiş feature branch'leri bul
git branch --merged develop | grep "feature/"
# Son 30 günde dokunulmamış branch'leri listele
git for-each-ref --format='%(refname:short) %(committerdate)' refs/heads/ |
awk '$2 < "'$(date -d '30 days ago' '+%Y-%m-%d')'"'
Commit Mesajı Disiplini: Her İki Stratejide de Kritik
Branch stratejisi ne olursa olsun, commit mesajı kalitesi çalışmayı sürdürülebilir kılar. Conventional Commits formatı burada çok işe yarıyor:
# İyi commit mesajı örnekleri
git commit -m "feat(auth): JWT token yenileme mekanizması eklendi"
git commit -m "fix(api): kullanıcı listesi pagination hatası düzeltildi"
git commit -m "perf(db): ürün arama sorgusu index eklenerek optimize edildi"
git commit -m "docs: API endpoint dökümanasyonu güncellendi"
git commit -m "refactor(cart): sepet hesaplama mantığı service layer'a taşındı"
# CHANGELOG otomatik üretmek için git log kullanımı
git log --oneline --no-merges v2.4.0..v2.5.0 | grep "^[a-f0-9]* feat"
Özellikle Git Flow’da release branch’ini açmadan önce commit geçmişini gözden geçirme alışkanlığı edinin. git log develop --oneline --since="2023-10-01" komutu size son dönemdeki değişikliklerin özetini verir ve release notlarını hazırlamanızı kolaylaştırır.
İki Strateji Arasında Hibrit Kullanım
Pratikte sıkça görülen bir durum var: Ekipler tam olarak ne birini ne de diğerini uyguluyor. Özellikle orta ölçekli ekiplerde şu hibrit yaklaşım sıkça işe yarıyor:
Ana branch’ler: main ve develop
Feature branch’ler GitHub Flow mantığıyla açılıp kapatılıyor ama develop’a merge ediliyor. Belirli aralıklarla develop main’e alınıyor ve tag atılıyor. Hotfix’ler için main’den branch açılıyor.
# Hibrit yaklaşımda typical workflow
git checkout develop
git checkout -b feature/bildirim-sistemi
# Geliştirme...
git push origin feature/bildirim-sistemi
# PR açılır -> develop'a merge edilir
# Haftalık release zamanı
git checkout main
git merge --no-ff develop
git tag -a v$(date +%Y.%W) -m "Haftalık release $(date +%Y-%m-%d)"
git push origin main --tags
Bu yaklaşımın avantajı şu: Sürekli deploy yapabilirsiniz ama yine de release noktalarınız belirgin ve izlenebilir kalır. Özellikle “müşteriye fatura keseceğimiz versiyonu bilmem gerekiyor” diyen iş birimleriniz varsa bu esneklik değerlidir.
Hangi Stratejiyi Seçmelisiniz?
Bunu belirleyecek sorular var. Bunları kendinize sorun:
Git Flow size göre ise:
- Ürününüzün belirlenmiş release tarihleri var
- Aynı anda birden fazla versiyonu production’da tutuyorsunuz (v1.x ve v2.x gibi)
- QA süreci haftalarca sürebiliyor ve release dondurma periyodlarınız var
- Kurumsal müşterileriniz versiyonlar arası uyumluluk bekliyor
- Ekibiniz büyük (10+ geliştirici) ve herkesin paralel olarak farklı özellikleri geliştirmesi gerekiyor
GitHub Flow size göre ise:
- Continuous deployment yapıyorsunuz veya yapmak istiyorsunuz
- Tek bir production ortamınız var
- Küçük-orta ekip (2-8 geliştirici)
- Özellikleriniz kısa ömürlü ve hızlı teslim edilebilir nitelikte
- Feature flag kullanıyorsunuz veya kullanmaya hazırsınız
- Startup veya SaaS ürün geliştiriyorsunuz
Pratik bir kural olarak şunu söyleyebilirim: Eğer “sürüm numarasına göre changelog tutmak zorundayım” diyorsanız Git Flow, “her deploy bir release” diyorsanız GitHub Flow doğru başlangıç noktasıdır.
Git Konfigürasyonu ve Ortak Standartlar
Hangi stratejiyi seçerseniz seçin, ekip genelinde bazı git konfigürasyonlarının standart olması hayat kurtarır:
# .gitconfig veya proje bazlı git config
git config --global pull.rebase true
git config --global merge.ff only
git config --global branch.autosetuprebase always
# Büyük projelerde merge stratejisi
git config --global merge.tool vimdiff
git config --global rerere.enabled true # Tekrar eden conflict çözümlerini hatırlar
# Branch koruma kuralları için (GitHub CLI ile)
gh api repos/:owner/:repo/branches/main/protection
--method PUT
--field required_status_checks='{"strict":true,"contexts":["ci/test"]}'
--field enforce_admins=true
--field required_pull_request_reviews='{"required_approving_review_count":1}'
rerere.enabled true ayarı özellikle Git Flow kullanan ve sık rebase yapan ekiplerde ciddi zaman tasarrufu sağlar. Aynı conflict’i bir kez çözdünüz mü, git bir dahaki seferde sizin için çözer.
Sonuç
Git Flow ve GitHub Flow arasındaki seçimde “doğru cevap” aramak yerine “doğru soru” sormak gerekiyor: Ürününüz ne sıklıkla deployment alıyor ve ekibiniz nasıl organize?
Git Flow, disiplinli bir orkestra gibi çalışır. Herkesin partisyonu bellidir, giriş zamanları nettir ama prova süreci uzundur. GitHub Flow ise caz grubu gibidir; temel kurallar vardır ama doğaçlama hızı ve esnekliği yüksektir.
Çoğu modern ekip için GitHub Flow veya ona yakın bir hibrit yaklaşım daha az sürtünme yaratır. Ama kurumsal yazılım geliştiriyorsanız, on-premise kurulumlarınız varsa veya uzun QA döngüleriniz mevcutsa, Git Flow’un getirdiği yapı kargaşayı önler.
Son olarak şunu belirtmekte fayda var: En iyi branch stratejisi, ekibinizin gerçekten uyguladığı stratejidir. Kağıt üzerinde mükemmel görünen ama pratikte yarım bırakılan ya da sürekli istisna yapılan bir strateji, basit ama tutarlı uygulanan bir stratejiden her zaman daha kötüdür. Seçtiğiniz yolu belgeleyin, ekibinizle tartışın ve birkaç ayda bir geriye dönüp “bu bize hala hizmet ediyor mu?” sorusunu sorun.
