Skip to content

Bölüm 7 / 12

Branching stratejileri

GitFlow, trunk-based, feature branch.

18 dakikalık okuma

İlk altı ders tek kişinin Git'iydi: komutlar, graf, geri alma. Bu ders ekibin Git'ine geçer. Git dallanmayı bedavaya verir; hangi dalların açılacağı, ne kadar yaşayacağı ve main'e nasıl gireceği ise Git'in değil ekibin kararıdır — ve 1. dersin tanımıyla bir sosyal sözleşmedir. Ders üç yerleşik stratejiyi (GitFlow, GitHub Flow, trunk-based) mekanizmasıyla ve maliyetiyle anlatır; sürüm ve hotfix akışını, "PR düğmesinin üç seçeneği"ni (3. ve 6. dersin senedi) ve 3. dersten beri ertelenen trunk-based ↔ GitFlow tartışmasını kapatır. Bitişte bir karar tablosu vardır: sözlüde "ekibinizde hangi stratejiyi kullanırsınız" sorusuna tek kelimeyle değil, gerekçeli bir seçimle cevap vereceksin.

01Ne öğreneceksin

  • Stratejinin üç sorusu: dallar nasıl düzenlenir, ne kadar yaşar, main'e nasıl girer; strateji ↔ entegrasyon sıklığı bağı
  • GitFlow: beş dal türü, akış, uygun olduğu yer ve gizli maliyeti (çift merge, uzun ömürlü develop)
  • GitHub Flow ve GitLab Flow: "main her an dağıtılabilir"; ortam ve sürüm dalları
  • Trunk-based development: kısa dallar, özellik bayrağı, soyutlamayla dallanma, ön şartları
  • Sürüm ve hotfix akışı: release dalı yalnız kesim için, düzeltme main'de, cherry-pick -x, annotated tag
  • Merge davranışı kararı: merge commit / squash / rebase-ff — PR düğmesinin üç seçeneği ve sonuçları
  • Dal koruma kuralları, isimlendirme, monorepo notu; DORA metrikleri ile dal ömrünün bağı
  • "Hangi durumda hangisi" karar tablosu ve kamu kurumu senaryosu

02Strateji nedir ve neden ekip kararıdır

3. ders dalı 41 baytlık bir dosya olarak tanıttı; açmak ve silmek bedava. Ama bir dal yaşadığı sürece ekip için bir soru üretir: bu daldaki iş ne zaman herkesin işiyle buluşacak? 5. ders bunun bedelini gösterdi — dal ne kadar uzun yaşarsa merge o kadar pahalı, çatışma o kadar büyük. Bir branching stratejisi, ekibin şu üç soruya verdiği yazılı cevaptır:

  1. Dallar nasıl düzenlenir? Hangi kalıcı dallar var (yalnız main mi, develop de var mı, ortam dalları var mı), geçici dallar hangi türde açılır, adları nedir.
  2. Dallar ne kadar yaşar? Saatler mi, günler mi, sürüm boyunca mı — bu, entegrasyon sıklığının doğrudan ölçüsüdür.
  3. İş main'e nasıl girer? Doğrudan commit mi, PR mi; merge commit mi, squash mı, rebase mi; kimin onayıyla; hangi kontrollerden sonra.

Bu cevapların hiçbirini Git dayatmaz — 1. dersin "sunucu = sosyal sözleşme" cümlesinin devamıdır: Git her modeli aynı kolaylıkla taşır. Ekip ise yalnızca birini seçmek zorundadır, çünkü strateji üstüne kurulan her şey (CI'ın hangi dalda koşacağı, sürümün nereden kesileceği, hotfix'in nereye gideceği) o seçime bağlıdır. Stratejilerin hepsi tek bir eksende sıralanır: entegrasyon ne kadar sık? Bir uçta haftalar süren dallar ve büyük birleştirmeler, diğer uçta günde birkaç kez main'e giren küçük commit'ler. Bu dersin üç stratejisi o eksenin üç noktasıdır; kalan her şey ayrıntıdır.

03GitFlow

2010'da Vincent Driessen'in yayımladığı model, uzun süre "Git böyle kullanılır" sanılan ilk yerleşik stratejidir. İki kalıcı, üç geçici dal türü vardır:

DalÖmürNereden açılırNereye birleşirAnlamı
mainkalıcı——Yalnız üretimdeki sürümler; her commit'i bir sürüm tag'i
developkalıcımain'den bir kezrelease üzerinden main'eBir sonraki sürümün entegrasyon dalı
feature/*günler–haftalardevelopdevelopTek özellik
release/*günlerdevelopmain ve developSürüm dondurma: yalnız hata düzeltme, sürüm numarası, doküman
hotfix/*saatlermainmain ve developÜretimdeki acil düzeltme
main     ── v1.0 ──────────────────────── v1.0.1 ─────────── v1.1 ──
              │                              ▲                    ▲
              │              hotfix/1.0.1 ───┤──┐                 │
              │                              │  │   release/1.1 ──┤──┐
develop  ─────┴── o ── o ── o ── o ── o ── o ┴──┴── o ── o ────────┴──┴── o ──
                  │              ▲
                  └ feature/x ───┘

Akış: özellik develop'tan açılır, develop'a döner; sürüm zamanı develop'tan release/1.1 kesilir, orada yalnız düzeltme yapılır, bitince hem main'e hem develop'a merge edilir ve main'de v1.1 tag'lenir (4. ders: annotated). Üretimde hata çıkarsa main'den hotfix/1.0.1 açılır, o da iki yere birden merge edilir. Uygun olduğu yer bellidir: paketlenip müşteriye teslim edilen yazılım, aynı anda birden fazla sürümün üretimde desteklenmesi (1.0 kullanan müşteri hâlâ yama alıyor), sürüm arasında resmî bir dondurma ve onay evresi gerektiren düzenleyici ortamlar.

Maliyeti tablodaki iki koyu hücrede saklıdır. Release ve hotfix dalları iki yere merge edilir; birini unutmak klasik GitFlow hatasıdır — üretimde düzeltilen hata bir sonraki sürümde geri gelir, çünkü develop'a hiç girmemiştir. İkincisi, develop uzun ömürlü bir entegrasyon dalıdır: özellikler haftalarca kendi dallarında yaşar, develop'ta buluşur, main'e ancak sürümde ulaşır; 5. dersin "büyük çatışma" ve 3. dersin "merge geciktikçe pahalanır" uyarısı tam bu modelin günlük hayatıdır. Üçüncüsü, "sürekli dağıtım" ile uyumsuzdur: main yalnız sürümlerde ilerler, günde beş dağıtım yapan bir web uygulaması için dal töreni iş yükünden fazladır. Driessen bunu 2020'de yazısına eklediği notla kendisi söyledi: sürekli teslimat yapan ekipler daha basit bir akışa, GitHub Flow'a bakmalı. Sözlüde GitFlow'u anlatırken bu iki cümleyi birlikte söyleyebilmek — "ne zaman uygun" ve "ne zaman fazla" — kıdemi gösterir.

04GitHub Flow ve GitLab Flow

GitHub Flow tek kalıcı dal tanır: main, ve bir kural koyar — main her an dağıtılabilir olmalıdır. Her iş kısa ömürlü bir daldan açılır, PR ile (8. ders) tartışılır ve doğrulanır, birleştiğinde dağıtılır. Özgün tarifte dağıtım merge'den önce gelir: dal üretime alınır, sorun çıkmazsa main'e girer; çoğu ekip bugün "merge = dağıt" olarak uygular. Sürüm dalı, develop, hotfix töreni yoktur: hotfix de sıradan bir kısa daldır, çünkü main zaten üretimdir.

main ── o ── o ── o ──────── M ── o ─── M ── o ──
                    └ ozellik/… ┘      └ hotfix/… ┘   (her M = PR merge → dağıtım)

Uyduğu yer: tek üretim ortamı olan, sık dağıtılan web uygulaması ve servisler. Uymadığı yer: aynı anda birden fazla sürümü desteklemek, dağıtım tarihinin kurumca belirlendiği "pencere" düzeni, ya da "main'e girdi ama henüz yayınlanmadı" ara durumunu temsil etme ihtiyacı. GitLab Flow bu boşluklar için iki uzantı önerir: ortam dalları (main → staging → production; kod aşağı doğru yalnız merge ile akar, dağıtım = ilgili dala merge) ve sürüm dalları (release/1.4, yalnız düzeltme alır). Her iki uzantıda da tek kural vardır ve bu dersin en önemli ilkelerinden biridir: "upstream first" — düzeltme önce main'de yapılır, sonra ortam/sürüm dalına taşınır; asla tersi. Aksi hâlde GitFlow'un "unutulan ikinci merge" hatası başka adla geri gelir.

05Trunk-based development

Eksenin sık entegrasyon ucu. Tek kalıcı dal (trunk = main), herkes ona en az günde bir commit gönderir: ya doğrudan (küçük, disiplinli ekiplerde), ya ömrü bir-iki günü geçmeyen kısa dallardan PR ile. 3. dersin cümlesi buradan geliyordu: "dal ne kadar uzun yaşarsa merge o kadar pahalı" — trunk-based bu bedeli sıfıra yakın tutmak için dalı kısa tutar. Haftalar sürecek bir iş nasıl günlük parçalarla main'e girer? İki teknikle:

Özellik bayrağı (feature flag). Yeni kod yolu main'e girer ama bir anahtarla kapalı durur; bayrak açılana kadar kullanıcı görmez. Yayın, dağıtımdan ayrılır: kod haftalar önce üretimdedir, "açma" bir yapılandırma değişikliğidir — istenirse yalnız belli kullanıcılara (yüzde, kurum, rol) açılır, sorun çıkarsa kod geri alınmadan kapatılır.

if (bayraklar.Acik("yeni-ucret-hesabi", basvuru.KurumId))
    return yeniHesap.Hesapla(basvuru);
return eskiHesap.Hesapla(basvuru);

Bayrakların türü farklıdır ve ömürleri de: release bayrağı (bitmemiş özelliği saklar; günler-haftalar, bitince silinir), deney bayrağı (A/B; deney bitince silinir), işletim bayrağı (yük altında pahalı özelliği kapatmak; kalıcı olabilir, 19. hattın devre kesicisine komşu), yetki bayrağı (belirli kullanıcılara erken erişim). Kıdem kuralı: her bayrak teknik borçtur (15-11) — açılış tarihi ve son kullanma tarihi olmayan bayrak, iki yıl sonra kimsenin dokunmaya cesaret edemediği ölü bir if olur; bayrak kaldırma işi backlog'a bayrakla aynı gün yazılır. Test tarafı da vardır: bayrağın iki hâli de test edilir, kombinasyon patlamasına karşı bayrak sayısı az tutulur.

Soyutlamayla dallanma (branch by abstraction). Büyük bir değişimi (ORM değiştirmek, ödeme sağlayıcısını taşımak) dalda değil main'de, adım adım yapmak: eski uygulamanın önüne bir arayüz konur, çağıranlar arayüze taşınır, yeni uygulama arayüzün arkasında bayrakla büyütülür, tamamlanınca eski kaldırılır. Her adım küçük, her adım main'de, hiçbir adımda çalışan sistem bozulmaz — 4. hattın DIP'i (tas-solid-dip) ve 15-11'in strangler deseni burada süreç aracı olur.

Trunk-based'in sürüm dalı vardır ama farklı anlamda: yalnız kesim için (branch for release). Sürüm zamanı main'den release/1.4 açılır, tag'lenir, dağıtılır; üzerinde geliştirme yapılmaz, düzeltme main'de yapılıp cherry-pick -x ile taşınır (06. bölüm). Ön şartları vardır ve pazarlıksızdır: hızlı CI (her push'ta dakikalar içinde build + test — 18. hat), güvenilir test ağı (15. hat; main her an dağıtılabilir olacaksa "sonra test ederiz" yoktur), küçük ve atomik commit'ler (2. ders), kod incelemesinin dalı bekletmemesi (8. ders: saatler, günler değil). DORA'nın yıllık "State of DevOps" araştırmaları yıllardır aynı bulguyu veriyor: az sayıda aktif dal ve bir günden kısa dal ömrü, yüksek performanslı ekiplerle güçlü biçimde ilişkili. Bu nedensellik değil korelasyon; ama mekanizması açık — küçük parça, küçük risk, hızlı geri bildirim.

06Sürüm ve hotfix akışı

Sözlüde "sürüm nasıl çıkar" sorusu, stratejiden bağımsız olarak şu adımların bilinmesini bekler; adımların dağılımı stratejiye göre değişir ama parçalar aynıdır:

  1. Kesim. Sürüme girecek son commit belirlenir. GitFlow'da develop'tan release dalı; trunk-based'de main'den release/1.4 (ya da yalnız tag). Sürüm numarası SemVer (15-11): kırıcı değişiklik MAJOR, geriye uyumlu özellik MINOR, düzeltme PATCH.
  2. Dondurma. Release dalına yalnız düzeltme girer; yeni özellik main'e (ya da develop'a) akmaya devam eder. "Bu da girsin" isteğinin cevabı hayırdır; sürüm dondurulmazsa hiç çıkmaz.
  3. Tag. Dağıtılan commit git tag -a v1.4.0 -m "…" ile işaretlenir ve --follow-tags ile push edilir (4. ders). Tag taşınmaz; hata varsa v1.4.1 gelir. git describe derleme numarasını bu tag'den türetir (18. hat).
  4. Dağıtım + duyuru. Changelog (11. ders) ve dağıtım (18. hat).

Hotfix akışında iki okul vardır ve farkı bilmek sınav sorusudur. GitFlow okulu: düzeltme main'den (üretimden) açılan hotfix dalında yapılır, main'e ve develop'a merge edilir. Trunk-based / GitLab okulu (upstream first): düzeltme main'de yapılır, test edilir, sonra sürüm dalına taşınır:

git switch main && git switch -c fix/son-gun-saati
…düzelt, test et, PR ile main'e al…                 (main'de commit: 3f2a1c0)
git switch release/1.4
git cherry-pick -x 3f2a1c0                          (6. ders: -x kaynağı mesaja yazar)
git tag -a v1.4.1 -m "Son gün 23:59 hatası" && git push --follow-tags origin release/1.4
git cherry main release/1.4                         (taşınmamış commit kaldı mı?)

İkinci okulun gerekçesi: düzeltmenin gelecek sürümde unutulması imkânsızdır, çünkü zaten main'dedir; sürüm dalı her zaman main'in bir alt kümesidir; ve git cherry ile "hangi düzeltme hangi sürüme taşındı" denetlenebilir. Birden fazla sürümün destekte olduğu üründe (1.3 ve 1.4 aynı anda) aynı commit her destekli sürüm dalına ayrı ayrı cherry-pick edilir — destek penceresi ne kadar genişse bakım maliyeti o kadar büyür; "kaç sürümü destekliyoruz" bir ürün kararıdır ve dal sayısını belirler.

07Merge davranışı kararı: PR düğmesinin üç seçeneği

3. ve 6. dersin senedi. Bitmiş iş main'e üç biçimde girer ve barındırma platformları PR düğmesinde tam bu üçünü sunar (GitHub: "Create a merge commit / Squash and merge / Rebase and merge"; Azure DevOps ve GitLab aynı üçlü, ek olarak "yarı doğrusal" — önce rebase, sonra --no-ff merge commit):

Merge commit (--no-ff)SquashRebase + fast-forward
Main'e girenDalın tüm commit'leri + 1 merge commitTek yeni commitDalın commit'leri yeniden yazılarak (yeni özetler)
Geçmiş şekliDallı; "hangi PR" merge commit'ten okunurDüz; 1 PR = 1 commitDüz; PR sınırı görünmez
Bisect / blameMerge commit gürültüsü; --first-parent ile temizEn temiz; ama büyük commit'te suçlu satır bulmak zorTemiz, ince taneli
Geri almarevert -m 1 (6. ders)Tek revertCommit sayısı kadar revert ya da aralık
Dalın commit temizliğiYazara bağlı — "WIP", "typo" main'e girerÖnemsiz; hepsi erirŞart — her commit main'de yaşayacak
Merge sonrası dal-d ile silinir-d reddeder, -D gerekir (3. ders)Yerel dal eski özetlerde; sil, yeniden çek
İmzalı commitKorunurYeni commit platform imzalarYeniden yazıldığı için yazar imzası düşer

Karar ilkesi: küçük PR'larda squash — bir PR bir değişiklik birimidir, tek commit olarak main'e girer, tek revert ile geri gelir, PR açıklaması commit mesajı olur. Büyük ama iyi kürate edilmiş PR'larda (6. dersin interactive rebase'iyle temizlenmiş, her commit'i kendi başına anlamlı) rebase-ff ya da --no-ff merge; ilki düz, ikincisi "PR sınırı" bilgisini saklar. Kıdem tuzağı: squash, uzun ömürlü dallar arasında tekrar tekrar kullanılırsa (develop'a squash, sonra develop'tan tekrar dal, tekrar squash) Git aynı değişiklikleri "yeni" sanır ve her seferinde çatışma üretir — squash, kısa ömürlü dalın main'e girişi için vardır, GitFlow'un develop↔release trafiği için değil. Bir ekipte tek seçenek zorlanır: platform ayarında diğer ikisi kapatılır (GitHub: "Allow squash merging" tek başına), yoksa geçmiş kişiye göre değişen bir karışım olur.

08Dal koruma, isimlendirme, monorepo

Strateji yazılı kural olarak kalırsa unutulur; sunucuya dal koruma olarak yazılırsa uygulanır (4. dersin "force yasağı" senedinin sunucu tarafı; ayrıntı 8. derste): main'e doğrudan push yok, yalnız PR; force push yok; zorunlu durum kontrolleri (CI yeşil); en az N onay; isteğe bağlı doğrusal geçmiş (yalnız squash/rebase) ve imzalı commit. Bu kurallar yöneticilere de uygulanır — "admin istisnası" kuralın yokluğudur.

İsimlendirme, stratejinin görünen yüzüdür ve otomasyona girdi olur: tür/is-kaydi-kisa-ad — feature/BAS-142-son-gun-kurali, fix/BAS-201-saat-dilimi, release/1.4. Tür öneki hangi dalın ne olduğunu grafta söyler, iş kaydı numarası PR'ı iş yönetimine otomatik bağlar (8. ders), kalanı insana hitap eder. 3. dersin ref kısıtları geçerlidir: boşluk, iki nokta, .. yok. Ekip bu kalıbı sunucu tarafında da zorlayabilir (dal adı deseni kuralı).

Monorepo notu: bazı kurumlar tüm projeleri tek depoda tutar (API, web, ortak kütüphaneler). Strateji tercihini değiştirmez ama iki şeyi zorlar: trunk-based dışında bir model monorepo'da hızla kilitlenir (bir sürüm dalı = tüm projeler donar), ve CI "hangi klasör değişti" bilgisine göre yalnız etkilenen projeleri koşturmalıdır (18. hat yol filtreleri). Git tarafında git sparse-checkout yalnız ilgilendiğin klasörleri çalışma alanına indirir, git log -- klasor/ proje bazlı geçmiş verir, kod sahipliği klasör başına tanımlanır (8. ders CODEOWNERS). Bir depoya girip git log --graph --oneline --all | head -50 ile hangi stratejinin uygulandığını okuyabilmek — uzun yaşayan develop çizgisi, düzenli tag'ler, tek düz çizgi — alışkanlık hâline getirilecek bir teşhis becerisidir.

09Hangi durumda hangisi: karar tablosu ve DORA bağı

DurumTrunk-basedGitHub Flow (+ release dalı)GitFlow
Dağıtım sıklığıGünde çok kezGünlük–haftalıkHaftalar–aylar
Sürüm modeliTek canlı sürüm (SaaS, iç servis)Tek canlı sürüm; ara sıra sürüm dalıÇoklu desteklenen sürüm, paketlenmiş ürün
Test/CI olgunluğuŞart: hızlı CI, güvenilir testlerPR'da CI yeterliRelease evresinde elle test toleransı var
Ekip boyutuHer boyut; büyükte bayrak disiplini şartKüçük–ortaBüyük, dağınık, sürüm yöneticisi olan
Onay/dağıtım penceresiBayrakla: kod erken girer, açılış onaylaRelease dalı + tag ile pencereye uyarRelease dalı doğal onay evresi
Ana riskBayrak borcu, disiplinsiz commitÇoklu sürüm desteği yokUnutulan çift merge, geç entegrasyon

Kamu kurumu senaryosu. Şartnameyle alınmış bir sistem, kabul testi (UAT) ortamı, değişiklik kurulunun onayladığı dağıtım pencereleri (ayda iki), tek üretim ortamı, kurum içi 8 kişilik ekip. GitFlow'un çoklu sürüm desteği gereksizdir, saf GitHub Flow'un "merge = dağıt" varsayımı pencereye uymaz. Uygun cevap ortadadır: trunk-based/GitHub Flow + pencere başına release dalı — herkes kısa dallardan PR ile main'e girer, pencere öncesi main'den release/2026.09.2 kesilir ve UAT'ye çıkar, kabul edilen düzeltmeler main'de yapılıp cherry-pick -x ile dala taşınır, pencere günü dal tag'lenip dağıtılır. Bu, Microsoft'un Azure DevOps ekibinin "Release Flow" adıyla belgelediği düzenin aynısıdır. Bitmemiş özellikler bayrak arkasında main'de bekler; UAT'de açılıp üretimde kapalı kalabilir. Sözlüde bu senaryoyu "GitFlow kullanırım" diye kapatan aday, çift merge'ü ve geç entegrasyonu üstlenmiş olur; gerekçeli hibrit cevap ayırt edicidir.

DORA bağı. Dört metrik: dağıtım sıklığı, değişiklik için lead time (commit'ten üretime), değişiklik hata oranı, geri getirme süresi. Dal ömrü, lead time'ın doğrudan bileşenidir — dalda bekleyen kod üretime gitmeyen koddur; büyük dal büyük dağıtımdır, büyük dağıtım yüksek hata oranı ve uzun geri getirmedir. Strateji seçimi bu dört sayıyı hedeflemenin aracıdır; sayılar 18. hatta ölçülür.

10Mini alıştırma — iki strateji, aynı depo

Yaklaşık 20 dakika · 4. dersin bare deposu ve bir klon

  1. GitFlow provası. develop aç. İki feature/ dalı aç, develop'a --no-ff ile birleştir. release/1.0 kes, bir "sürüm numarası" commit'i at, hem main'e hem develop'a merge et, main'de v1.0.0 annotated tag. Sonra main'den hotfix/1.0.1 aç, düzelt, yalnız main'e merge et ve develop'ı unut. git log develop..main: düzeltme develop'ta yok — sonraki sürümde hata geri gelir. Şimdi develop'a da merge et.
  2. Trunk-based provası. Yeni bir klonda yalnız main. Küçük bir fonksiyona if (bayrak) ile yeni bir yol ekle, bayrak kapalı, main'e commit. İki commit daha. release/1.1 kes ve tag'le. Main'de bir düzeltme commit'i at, cherry-pick -x ile release'e taşı; git cherry main release/1.1 çıktısını yorumla. Bayrağı açan tek satırlık commit'i at: "yayın" ile "dağıtım"ın ayrıldığını gör.
  3. Üç düğme. Üç commit'li bir dalı üç kopyada üç biçimde main'e al: merge --no-ff, merge --squash + commit, rebase + merge --ff-only. Her kopyada git log --graph --oneline ve git branch -d dal: hangisi reddetti, neden?
  4. Teşhis. İki klonun git log --graph --oneline --all çıktısını yan yana koy; hangi stratejinin uygulandığını grafın hangi özelliğinden anladığını üç maddeyle yaz.
  5. Karar. 09. bölümdeki kamu senaryosu için bir sayfalık strateji kararı yaz: dallar, ömür, merge davranışı, hotfix akışı, gerekçe. Bu belge 12. düğümün A çıktısının taslağıdır.

11Kendini sına

GitFlow'un dalları nelerdir, akış nasıl işler? Hangi durumda uygundur ve gizli maliyeti nedir?

İki kalıcı dal: main (yalnız üretim sürümleri, her commit tag'li) ve develop (sonraki sürümün entegrasyon dalı); üç geçici tür: feature/* (develop'tan açılır, develop'a döner), release/* (develop'tan kesilir, yalnız düzeltme alır, bitince hem main'e hem develop'a merge edilir ve main'de tag'lenir), hotfix/* (main'den açılır, hem main'e hem develop'a merge edilir). Uygun olduğu yer: paketlenip teslim edilen ürün, aynı anda birden fazla desteklenen sürüm, sürüm arasında resmî dondurma/onay evresi. Gizli maliyeti: release ve hotfix'in çift merge'ü — biri unutulursa üretimde düzeltilen hata sonraki sürümde geri gelir; uzun ömürlü develop ve haftalarca yaşayan feature dalları geç entegrasyon ve büyük çatışma üretir; main yalnız sürümlerde ilerlediği için sürekli dağıtımla uyumsuzdur. Modelin yazarı 2020'de sürekli teslimat yapan ekiplere daha basit bir akış (GitHub Flow) önermiştir.

Trunk-based development nedir? Haftalar sürecek bir iş günlük parçalarla main'e nasıl girer? Ön şartları nelerdir?

Tek kalıcı dal (trunk/main); herkes en az günde bir kez ona commit gönderir — doğrudan ya da ömrü bir-iki günü geçmeyen kısa dallardan PR ile. Büyük iş iki teknikle parçalanır: özellik bayrağı — yeni kod yolu main'e kapalı bir anahtarın arkasında girer, yayın dağıtımdan ayrılır, kısmi/kademeli açılır, sorun çıkarsa kod geri alınmadan kapatılır; bayrak türleri release/deney/işletim/yetki, her bayrak son kullanma tarihli teknik borçtur ve bitince silinir. Soyutlamayla dallanma — büyük değişim main'de adım adım: arayüz konur, çağıranlar taşınır, yeni uygulama bayrak arkasında büyür, eski kaldırılır. Sürüm dalı yalnız kesim içindir; düzeltme main'de yapılıp cherry-pick -x ile taşınır. Ön şartlar: dakikalar içinde koşan hızlı CI, güvenilir test ağı (main her an dağıtılabilir), küçük atomik commit'ler, dalı bekletmeyen hızlı kod incelemesi. DORA araştırmaları kısa dal ömrü ve az aktif dalı yüksek performansla ilişkilendirir.

PR düğmesinin üç seçeneği (merge commit / squash / rebase) neyi değiştirir? Hangisini ne zaman seçersin; squash'ın tuzağı nedir?

Merge commit (--no-ff): dalın tüm commit'leri + bir merge commit; dallı geçmiş, "hangi PR" merge commit'ten okunur, revert -m 1 ile geri alınır, bisect/blame'de gürültü (--first-parent yardım eder), dal -d ile silinir. Squash: tek yeni commit; düz geçmiş, 1 PR = 1 commit, tek revert, dal temizliği önemsiz; ama -d reddeder (-D gerekir) ve büyük commit'te suçlu satır zor bulunur. Rebase + ff: commit'ler yeniden yazılarak (yeni özetler) düz geçmişe girer, ince taneli bisect; her commit main'de yaşayacağı için dal temizliği şart, yazar imzası düşer, yerel dal eski özetlerde kalır. Karar: küçük PR'larda squash; iyi kürate edilmiş büyük PR'larda rebase-ff ya da PR sınırını saklamak için --no-ff; ekipte tek seçenek platform ayarıyla zorlanır. Squash tuzağı: uzun ömürlü dallar arasında tekrar tekrar squash (develop↔release trafiği) Git'in aynı değişiklikleri yeni sanmasına ve her seferinde çatışmaya yol açar — squash, kısa ömürlü dalın main'e girişi içindir.

Hotfix nasıl çıkarılır; "upstream first" ne demektir? Onaylı dağıtım pencereleri olan bir kamu kurumu için hangi stratejiyi önerirsin, neden?

İki okul: GitFlow'da hotfix main'den açılır, hem main'e hem develop'a merge edilir. Upstream first (trunk-based/GitLab Flow): düzeltme önce main'de yapılır, test edilir ve PR ile girer; sonra cherry-pick -x ile sürüm dalına taşınır, dalda v1.4.1 annotated tag atılır, --follow-tags ile push edilir; git cherry taşınmamış commit kaldı mı diye denetler. Gerekçesi: düzeltme main'de olduğu için gelecek sürümde unutulamaz, sürüm dalı hep main'in alt kümesidir; birden fazla desteklenen sürüm varsa her dala ayrı cherry-pick — destek penceresi dal sayısını ve bakım maliyetini belirler. Kamu senaryosu (tek üretim, UAT, ayda iki onaylı pencere, 8 kişi): GitFlow'un çoklu sürüm desteği gereksiz, saf GitHub Flow'un "merge = dağıt"ı pencereye uymaz; öneri trunk-based/GitHub Flow + pencere başına release dalı (Release Flow): kısa dallardan PR ile main, pencere öncesi main'den kesilen release dalı UAT'ye, düzeltmeler main'de yapılıp cherry-pick ile dala, pencere günü tag + dağıtım; bitmemiş özellikler bayrak arkasında. Gerekçe: geç entegrasyon ve çift merge maliyeti yok, onay evresi release dalında doğal olarak var.

12Sınav köşesi

Yazılıda nasıl sorulur

(1) GitFlow'daki dal türlerini ve her birinin nereden açılıp nereye birleştiğini yazınız. (2) Trunk-based development nedir; feature branch modelinden farkı nedir? (3) Feature flag (özellik bayrağı) nedir, ne işe yarar? (4) Hotfix nasıl çıkarılır; release dalına nasıl taşınır? (5) Squash merge ile merge commit arasındaki fark nedir? (6) Uzun ömürlü dalların sakıncaları nelerdir? (7) Korumalı dal (protected branch) ne demektir? (8) Sürekli dağıtım yapan bir ekip için hangi branching stratejisi uygundur, neden? (9) Sürüm numaralandırmada SemVer kuralları nelerdir? (10) DORA metrikleri nelerdir?

Sözlüde nasıl anlatılır — 2 dakikalık taslak

Düzen: (1) Çerçeve — "Strateji, dalların nasıl düzenlendiği, ne kadar yaşadığı ve main'e nasıl girdiğinin ekip kararıdır; hepsi tek eksende sıralanır: entegrasyon ne kadar sık." (2) Üçlü — "GitFlow çoklu sürüm ve resmî dondurma için; bedeli çift merge ve geç entegrasyon. GitHub Flow main'i her an dağıtılabilir tutar. Trunk-based günlük entegrasyon, kısa dal, özellik bayrağı; ön şartı hızlı CI ve güvenilir test." (3) Sürüm — "Sürümü main'den keser, annotated tag atarım; düzeltmeyi main'de yapıp cherry-pick -x ile sürüm dalına taşırım — upstream first, düzeltme gelecek sürümde unutulmaz." (4) Merge davranışı — "Küçük PR'larda squash, kürate edilmiş büyük PR'larda rebase ya da --no-ff; ekipte tek seçenek, platform ayarıyla." (5) Kıdem vuruşu — "Onaylı dağıtım pencereli bir kurumda trunk-based + pencere başına release dalı kurarım: kod erken girer, bayrak arkasında bekler, UAT release dalında, hotfix cherry-pick ile. Dal ömrü DORA lead time'ının doğrudan bileşenidir; strateji o sayıları hedeflemenin aracıdır."