Git Flow, GitHub Flow ve trunk-based: hangi Git workflow'unu seçmeli?
Git Flow, main ve develop gibi uzun ömürlü branch'ler ile feature, release ve hotfix geçici branch'lerini kullanan bir branch modelidir; planlı sürümleri olan ürünlere uygundur. Sık deploy yapan web servislerinde genellikle daha basit olan GitHub Flow (main'den kısa branch'ler ve pull request) ya da feature flag'li trunk-based development tercih edilir.
Git workflow nedir ve seçimi neden önemli
Git workflow, ekibin hangi branch'lerin var olacağı, nereden açılacakları, nereye birleştirilecekleri ve sürüme hazır sayılmak için neyin gerektiği konusundaki anlaşmasıdır. Git bunların hiçbirini dayatmaz; anlaşma yoksa herkes kendi bildiği gibi çalışır, bir ay sonra depoda onlarca branch olur, hangi kodun canlıda olduğu belli olmaz ve birleştirmeler saatlerce süren çakışmalara dönüşür.
En bilinen modeller Git Flow, GitHub Flow (Feature Branch Workflow'un bir varyantı) ve trunk-based development'tır. Bunlar «eski ve yeni» değil, farklı koşullara göre araçlardır: ne sıklıkta sürüm yayımladığınıza, aynı anda kaç sürümü desteklediğinize ve otomatik testlerinizin ne kadar güçlü olduğuna bağlı olarak seçilir.
Git Flow: develop ve release branch'li model
Git Flow'u Vincent Driessen 2010 yılında tanımladı. Model iki uzun ömürlü branch üzerine kuruludur:
- main (eski projelerde master) — yalnızca yayımlanmış kod; buradaki her commit bir sürüme karşılık gelir ve etiketle işaretlenir;
- develop — bir sonraki sürüm için hazır özelliklerin birleştirildiği entegrasyon branch'i.
Buna üç tür geçici branch eklenir:
| Branch | Nereden açılır | Nereye birleşir | Amaç |
|---|---|---|---|
| feature/* | develop | develop | Yeni bir özelliğin geliştirilmesi |
| release/* | develop | main ve develop | Sürümün stabilize edilmesi: hata düzeltmeleri, sürüm numarası, dokümantasyon |
| hotfix/* | main | main ve develop | Yayımlanmış sürümdeki acil düzeltme |
Git Flow'u saf Git ile uygulamak
Bir özelliğin ve bir sürümün döngüsü şöyle görünür:
# özellik
git switch develop
git switch -c feature/cart-discounts
# ... commit'ler ...
git switch develop
git merge --no-ff feature/cart-discounts
git branch -d feature/cart-discounts
# sürüm
git switch -c release/1.4.0 develop
# ... sürüm numarası düzeltmeleri ve hata düzeltmeleri ...
git switch main
git merge --no-ff release/1.4.0
git tag -a v1.4.0 -m "Release 1.4.0"
git switch develop
git merge --no-ff release/1.4.0
git branch -d release/1.4.0
--no-ff bayrağı bu modelde çok önemlidir: hızlı ileri sarmanın mümkün olduğu yerde bile bir merge commit'i oluşturur ve geçmişte hangi commit'lerin tek bir özelliğe ya da sürüme ait olduğu görünür kalır.
git-flow eklentisi
Bu komut dizilerini elle yazmamak için git-flow yardımcı aracı vardır (bugün genellikle bakımı yapılan çatal sürüm kurulur; paket yöneticilerinde adı çoğunlukla git-flow-avh'dir). Araç alt komutlar ekler:
git flow init -d
git flow feature start cart-discounts
git flow feature finish cart-discounts
git flow release start 1.4.0
git flow release finish 1.4.0
git flow hotfix start 1.4.1
git flow hotfix finish 1.4.1
git flow init branch adlarını ve önekleri sorar (-d ile varsayılan değerleri kabul eder), finish komutları ise gerekli tüm birleştirmeleri yapar, etiketi koyar ve geçici branch'i siler. Birçok Git GUI istemcisi de Git Flow'u düğmelerle destekler.
Git Flow'un artıları ve eksileri
Artıları: net bir yapı, kodun durumunun anlaşılır olması (main — müşterideki sürüm; develop — bir sonraki sürüm), sürüm için ayrı bir stabilizasyon evresi ve hotfix'leri desteklemenin kolaylığı. Bu model mobil uygulamalar, paketlenmiş yazılımlar, kütüphaneler ve donanım yazılımları gibi, sürümün bir mağaza incelemesinden geçtiği ya da müşteride kurulduğu durumlara iyi oturur.
Eksileri: çok sayıda branch ve birleştirme olur, uzun ömürlü feature branch'leri develop'tan giderek uzaklaşır ve release ile hotfix'lerin çift birleştirmesi kolayca unutulur. Günde birkaç kez deploy eden bir web servisi için release branch'leri bürokrasiye dönüşür. Modelin yazarı 2020'de makalesine bir not ekledi: sürekli dağıtılan yazılımlar için GitHub Flow gibi daha basit yaklaşımlara bakmak gerektiğini belirtti.
GitHub Flow: kısa branch'ler ve pull request
GitHub Flow, Feature Branch Workflow'un hafifletilmiş bir hâlidir. Kuralları birkaç maddeye sığar:
- main her zaman çalışır durumdadır ve deploy'a hazırdır.
- Her iş, anlamlı bir adı olan ve main'den açılan bir branch'te yapılır.
- Branch düzenli olarak sunucuya gönderilir ve tartışma için pull request (merge request) açılır.
- İnceleme ve yeşil CI sonrasında branch main'e birleştirilir.
- main'e birleşen her şey hemen deploy edilir.
git switch main
git pull
git switch -c feature/new-payment
# ... anlaşılır mesajlarla commit'ler ...
git push -u origin feature/new-payment
# pull request açılır, inceleme ve CI geçilir, main'e birleştirilir
Artıları: tek uzun ömürlü branch, en az kural, fikirden üretime en kısa yol ve doğal kod incelemesi. Eksileri: birden çok sürümü desteklemek ya da yayımdan önce stabilize etmek için hazır bir yer yoktur ve iyi otomatik testler olmadan «main her zaman hazır» bir dilekten öteye geçmez.
Ek ortam branch'leri (örneğin staging ve production) kullanan benzer bir yaklaşıma bazen GitLab Flow denir. Canlıya alım anında değil, bir takvime ya da elle kontrole göre yapılıyorsa bu daha uygundur.
Trunk-based development
Trunk-based development'ta bütün geliştiriciler değişikliklerini tek bir branch'e (trunk, yani main) sık sık — en az günde bir kez — entegre eder. Branch'ler varsa bile haftalar değil saatler yaşar. Tamamlanmamış işlevsellik main'e girer ama bir feature flag arkasında gizlenir:
if (featureFlags.isEnabled("new-checkout", user)) {
renderNewCheckout();
} else {
renderOldCheckout();
}
Başlıca avantajı, ciddi çakışmaların neredeyse hiç olmamasıdır: değişiklikler küçüktür ve herkes bağlamı hatırlarken birleşir. Model, sürekli entegrasyonu harfi harfine uygular ve hızlı CI'si ile yüksek test kapsamı olan olgun ekiplere uygundur. Release branch'lerine de izin verilir, ama bunlar yayımdan hemen önce trunk'tan açılır ve düzeltmeler önce trunk'a yazılıp cherry-pick ile oraya taşınır.
Eksileri: disiplin ve altyapı gerektirir — hızlı testler, flag'ler, izleme. Yeni başlayan biri her gün main'e commit yapmaktan çekinebilir; zayıf bir CI ise trunk'ı sürekli bozuk bir branch'e çevirir. Flag'ler de zamanında silinmelidir; yoksa kod ölü dallarla dolar.
Git Flow, GitHub Flow ve trunk-based karşılaştırması
| Ölçüt | Git Flow | GitHub Flow | Trunk-based |
|---|---|---|---|
| Uzun ömürlü branch'ler | main ve develop | main | main (trunk) |
| Feature branch'inin ömrü | Günler ve haftalar | Günler | Saatler ya da hiç branch yok |
| Sürüm sıklığı | Planlı sürümler | Birleştirildikçe | Sürekli |
| Birden çok sürümü destekleme | Evet, etiket ve hotfix ile | Zor | Release branch'leri ile |
| CI ve test gereksinimleri | Orta | Yüksek | Çok yüksek |
| Büyük çakışma riski | Yüksek | Orta | Düşük |
| Başlangıç eşiği | Kuralları öğrenmek gerekir | Minimum | Kültür ve feature flag gerekir |
| Tipik proje | Mobil uygulama, kütüphane, paketlenmiş yazılım | Web servisi, açık kaynak, startup | Sık deploy yapan büyük ürün |
Ekibiniz için git workflow nasıl seçilir
Birkaç soruyu yanıtlayın:
- Yayımlanmış birden çok sürümü desteklemek zorunda mısınız? Müşterileriniz 2.x ve 3.x sürümlerinde çalışıyorsa ve ikisine de düzeltme gerekiyorsa — Git Flow ya da release branch'li trunk-based.
- Ne sıklıkla deploy ediyorsunuz? Çeyrekte bir kez ise Git Flow engel olmaz. Her gün ise GitHub Flow ya da trunk-based seçin.
- Testlerinize ne kadar güveniyorsunuz? CI yavaşsa ve kapsam zayıfsa, zorunlu incelemeli GitHub Flow ile başlayın ve branch'leri zamanla kısaltın.
- Ekibin büyüklüğü ve deneyimi nasıl? Küçük ekiplere ve yeni başlayanlara en kolay yol GitHub Flow'dur: tek kural «main her zaman çalışır» ve her şey için pull request.
Pratik tavsiye: Git Flow'u «herkes öyle yapıyor» diye seçmeyin. Sorunlarınızı çözen en basit süreçle başlayın ve somut bir ihtiyaç ortaya çıktığında — örneğin bir stabilizasyon evresi ya da eski sürümlerin desteklenmesi — karmaşıklığı artırın.
Her workflow'da işe yarayan kurallar
- main'i sunucuda koruyun: doğrudan push yasak, zorunlu inceleme ve birleştirmeden önce yeşil CI.
- Branch adlarında anlaşın:
feature/,fix/,hotfix/ve görev numarası. - Branch'leri kısa tutun: branch ne kadar uzun yaşarsa birleştirmesi o kadar acıtır. main'i düzenli olarak merge ya da rebase ile kendi branch'inize alın.
- Pull request birleştirme stratejisini (merge commit, squash ya da rebase) seçin ve her yerde aynı şekilde kullanın.
- Sürümleri anlamlı sürüm numaralandırmasına (semantic versioning) uygun, açıklamalı etiketlerle (annotated tag) işaretleyin.
Üç modelde hotfix: aynı hata, üç süreç
Yaklaşımlar arasındaki fark, canlıdaki acil bir düzeltmede en iyi görülür.
Git Flow'da main'den hotfix/1.4.1 açılır, düzeltmeden sonra branch main'e v1.4.1 etiketiyle birleştirilir ve mutlaka develop'a (ya da varsa aktif release branch'ine) de birleştirilir. İkinci birleştirmeyi unutmak klasik bir hatadır: bir sonraki sürümde hata «geri döner».
git switch -c hotfix/1.4.1 main
git commit -am "İndirim hesabındaki hatayı düzelt"
git switch main && git merge --no-ff hotfix/1.4.1
git tag -a v1.4.1 -m "Hotfix 1.4.1"
git switch develop && git merge --no-ff hotfix/1.4.1
GitHub Flow'da hotfix, main'den açılmış, incelemede öncelik verilen sıradan kısa bir branch'tir. Birleştirildikten sonra aynı otomatik deploy ile canlıya gider; ayrı bir süreç yoktur.
Trunk-based'da düzeltme önce trunk'a commit edilir; canlıda bir release branch'i çalışıyorsa commit git cherry-pick -x <hash> ile oraya taşınır. -x bayrağı mesaja kaynak commit'e bağlantı ekler, böylece ilişki geçmişte görünür kalır. Sorun yeni bir özellikteyse çoğu zaman kodu hiç değiştirmeden yalnızca feature flag'i kapatmak yeter.
Mülakatta «hangi Git workflow'unu kullandınız» sorusu
Mülakatçı isimleri ezberlediğinizi değil, aralarındaki dengeleri anladığınızı kontrol eder. İyi bir cevap bir modeli adlandırır, branch'lerin ve incelemenin o modelde nasıl işlediğini anlatır ve projeye neden uyduğunu açıklar. Örneğin: «GitHub Flow kullandık: main'den açılan branch'ler, zorunlu incelemeli ve CI'li pull request'ler, birleştirme sonrası otomatik deploy. Git Flow'u seçmedik, çünkü haftada birkaç kez sürüm çıkarıyorduk ve release branch'leri sadece yavaşlatırdı.» Ek olarak, süreç büyüdüğünde neyi değiştireceğinizi söylemek artı puan kazandırır.
Kısaca
Git Flow, develop, release ve hotfix branch'lerinden oluşan katı bir modeldir; planlı sürümleri ve birden çok sürümün desteklenmesi gereken ürünlere uygundur. GitHub Flow daha basittir ve çoğu web projesine uyar; trunk-based development en yüksek hızı verir ama olgun bir CI ve feature flag gerektirir. Workflow'u moda yerine sürüm sıklığına ve test kalitenize göre seçin. Bu üç yaklaşımı, ekip uygulamalarını ve tipik hatalarını Git kursunda uygulamalı olarak ele alıyoruz.
Sık sorulan sorular
Git Flow eskidi mi?
Hayır, ama kullanım alanı daraldı. Sürekli deploy yapan web servisleri için fazla gelir; mobil uygulamalar, kütüphaneler ve paketlenmiş yazılım için hâlâ kullanışlıdır.
Sık sürüm çıkarıyorsak develop branch'ine ihtiyaç var mı?
Genellikle yoktur: develop, main'i tekrarlar ve fazladan bir birleştirme ekler. Sık sürümlerde main ve kısa feature branch'leri yeterlidir.
Git Flow içinde rebase kullanabilir miyim?
Evet, develop'u kendi paylaşılmamış ya da kişisel feature branch'inize rebase ile alabilirsiniz; ancak klasik modelde develop ve main'e son birleştirmeler, geçmişin yapısını korumak için merge --no-ff ile yapılır.
Feature flag, uzun süren bir feature branch'ine göre neden daha iyi?
Kod hemen main'e entegre olur ve kalan kod tabanından ayrışmaz; özelliğin açılması kodu geri almadan geri alınabilecek ayrı bir karar hâline gelir.
Git Flow'dan GitHub Flow'a nasıl geçilir?
Devam eden sürümleri tamamlayın, develop'u main'e birleştirin, CI'yi main'den deploy edecek şekilde yeniden ayarlayın ve develop'u silin. Yeni branch'leri yalnızca main'den açın.
Bu konu “Sıfırdan Güvenilir Geliştiriciye Git” kursunda uygulamalı olarak ayrıntılı işleniyor.
Kursa git