---
title: 'Dal Stratejileri'
source: 'https://academia.sh/tr/kurslar/dallanma-ve-isbirligi/dal-stratejileri'
course: 'Dallanma ve İşbirliği'
language: tr
updated: '2026-08-17T18:10:44+00:00'
license: 'CC BY-SA 4.0'
---

# Dal Stratejileri

Dalın ne kadar yaşadığı tarihçeye yazılanı belirler: aynı on iki işleme dal açılmadan 12, dört işlemede dönen düzende 15, her işlemede dönen düzende 24 işleme bırakır — ve ayrışma penceresi kapandığında birleştirme çakışması hiç doğmaz.

Önceki derste biçim seçimi tek bir birleşme için yapıldı: şu dal ana dala nasıl alınsın.
Ekipler bu kararı her seferinde yeniden vermez; bir kez verip kural hâline getirirler.

Kural yalnız birleşme anını kapsamaz. Dalların ne kadar yaşayacağını, kaç tane olacağını
ve ne sıklıkla ana dala döneceğini de belirler. Bu dersin sorusu şudur: aynı on iki
işlemelik gelişim ayrı dal düzenleriyle yürütüldüğünde tarihçeye ne kalır — ve dal ömrünün
kısalması hangi soruyu ortadan kaldırır.

Sürekli tümleştirmenin derleme, sınama ve dağıtım hattı açısından tartışması bu kursun
konusu değildir; **Sürekli Tümleştirme ve Teslimat** kursunda kurulur ve burada
tekrarlanmaz. Ölçülen tek şey, stratejinin **tarihçeye ne bıraktığıdır**.

## Dal Ömrü Bir Sayıdır

Dal stratejilerinin farkı tek bir büyüklüğe indirgenebilir: **bir dal ana dala dönmeden
önce kaç işleme biriktirir?** Bu sayı düzenin bütün öbür özelliklerini belirler.

**Uzun ömürlü dal** düzeninde sayı büyüktür. Dal bir işin tamamı bitene kadar açık kalır;
haftalarca yaşayabilir, onlarca işleme taşıyabilir. **Kısa ömürlü dal** düzeninde sayı
küçüktür; dal bir günden az yaşar, birkaç işleme taşır ve kapanır. Uçta bir düzen daha
vardır: dal hiç açılmaz ve herkes doğrudan ana çizgiye işler.

Üç düzen de aynı işi yaptırır ve aynı kodu üretir. Ayrıldıkları yer, tarihçeye bıraktıkları
kayıt ile dalların birbirinden ne kadar uzaklaştığıdır.

Kısa ömürlü düzenin günlük döngüsü birkaç komuta iner ve her turda aynen tekrarlanır.

```text
# öğretilen komut, örnek döküm — çalıştırılmamıştır

$ git switch -c olcum/esik ana
$ git commit -am "olcum: esik degerini yazdir"
$ git switch ana
$ git merge --no-ff olcum/esik
$ git branch -d olcum/esik
```

Beşinci satır düzenin ayırt edici parçasıdır: dal, işi ana dala girdikten hemen sonra
kapatılır. Kapatılmayan kısa dallar birikir ve dal listesi bir işaretçi çöplüğüne döner —
kayıt tarihçede kapanış işlemesi olarak zaten durduğu için işaretçinin kalması hiçbir
soruyu yanıtlamaz.

Uzun ömürlü dallar tek bir sınıf değildir. Bir işi taşıyan özellik dalı işi bitince
kapanır; bir yayımlanmış sürümü taşıyan dal ise kapanmaz, aylarca yaşar ve yalnız düzeltme
alır. İkincisinde ayrışma tasarım gereğidir — o dalın ana daldan uzaklaşması bir kusur
değil, amaçtır. Bu yüzden düzeltmeler oraya ve geliştirme çizgisine ayrı ayrı gitmek
zorunda kalır; dördüncü dersteki tek işleme kopyalama en sık burada kullanılır ve
kopyanın ödettiği yinelenme de burada birikir.

Adlandırma düzeni burada belirleyici olur. Kısa ömürlü düzende dal sayısı işin
büyüklüğüyle değil, dönüş sıklığıyla artar; bir işin birbirini izleyen turları ayrı ayrı
dallar olur. Dal adları bu turları aynı işe bağlayacak biçimde kurulmamışsa, tarihçedeki
dal kayıtları çoğalır ama hiçbiri işin tamamını göstermez. Adlandırmanın tarihçenin
birinci sorusuna katkısı bu kursun üçüncü dersinde kurulmuştu; burada aynı katkı dal
sayısıyla çarpılır.

## Ayrışma ve Çakışma Penceresi

İkinci dersin çakışması kurgunun üçüncü adımında doğdu: `olcum` ile `rapor` aynı dosyaya
dokundu. Ama çakışmanın doğması için aynı dosyaya dokunmak yetmez. **İki değişikliğin
paralel geliştirilmiş olması gerekir** — yani ikincisi başladığında birincisi henüz ana
dala girmemiş olmalıdır.

Birincisi zaten girmişse ikinci dal onu **taban olarak** görür. O zaman ortada iki taraflı
bir değişiklik yoktur; tek taraflı bir değişiklik vardır ve araç kararı kendiliğinden
verir. Aynı satır iki kez değişmiştir ama sırayla, çakışmadan.

Buradan dal ömrünün ikinci etkisi çıkar: dal ne kadar uzun yaşarsa ana daldan o kadar çok
işleme kadar **ayrışır** ve iki işin aynı dosyaya paralel dokunma olasılığı o kadar
büyür. Ayrışma bir zaman değil, bir işleme sayısıdır; ve düzenin sayısına eşittir.

Bu, kısa ömürlü dal düzeninin asıl gerekçesidir. Gerekçe "çakışmayı çözmek kolaylaşır"
değildir; **çakışmanın hiç doğmamasıdır**. Buna karşılık kısa dal, yarım kalmış işin ana
dalda durmasını gerektirir — yarım işin görünmeden durabilmesi için çalışma zamanında
kapatılabilir olması gerekir ve o düzeneğin kendisi Sürekli Tümleştirme ve Teslimat
kursunun konusudur.

Ölçümün varsayımları:

- **BR36** — Dal düzeni tek bir sayıyla temsil edilir: bir dal ana dala dönmeden önce kaç
  işleme biriktirir. **Sıfır**, dalın hiç açılmaması demektir.
- **BR37** — Her dönüş bir kapanış işlemesi yazar. Düzen dört işlemede dönüyorsa bu,
  birinci derste ölçülen birleştirme işlemesi biçiminin kendisidir.
- **BR38** — Kısa ömürlü düzende her tur **ayrı bir daldır** ve ayrı bir dal kaydı taşır;
  aynı işin turları arasında bağ kuran bir alan yoktur.
- **BR39** — Ayrışma, bir dalın ana daldan uzak kaldığı **en çok işleme sayısıdır** ve
  düzenin sayısına eşittir.
- **BR40** — İki dokunuşun **paralel** sayılması, ikincisinin dalı açıldığında birincisinin
  ana dala henüz girmemiş olmasıdır. Birleştirme çakışması yalnız paralel dokunuşlarda
  doğar.
- **BR41** — Zaman değerleri kurgunun kendi saatidir, ortama bağlı bir damga değildir;
  yalnız sıralama için kullanılır.
- **BR42** — Altı sorunun tanımı değiştirilmez; her düzen için ayrı ayrı çalıştırılır.
- **BR43** — Kümenin çözünürlüğü on iki işlemede **1/12**, altı soruda **1/6**.

## Ölçüm

```python
"""Dal stratejisi: dal omru tarihceye ne birakir.

Bolum 1 - dort dal duzeni: dal acmadan, bir, iki ve dort islemede bir donen.
Bolum 2 - ayni ortak dosyaya dokunan iki isleme paralel mi kaliyor.
"""
TOHUM = 20260813
DALLAR = ("olcum", "rapor", "kimlik")
DOSYALAR = {"olcum": "olcum.py", "rapor": "rapor.py", "kimlik": "kimlik.py"}
KUSURLU = ("rapor", 2)
ORTAK_DOSYA = "ayar.py"
DUZENLER = ((0, "dal açılmıyor"), (1, "her işlemede dönüş"),
            (2, "iki işlemede dönüş"), (4, "dört işlemede dönüş"))


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def gelisim():
    r, kayit, zaman = uretec(TOHUM), [], 0
    for adim in range(1, 5):
        for dal in DALLAR:
            zaman += 1 + r(3)
            dosya = (ORTAK_DOSYA if adim == 3 and dal in ("olcum", "rapor")
                     else DOSYALAR[dal])
            kayit.append({"dal": dal, "sira": adim, "dosya": dosya,
                          "kusurlu": (dal, adim) == KUSURLU, "zaman": zaman})
    return kayit


def bosalt(grup, dal, tur):
    """Bir turun islemeleri ve kapanis islemesi."""
    ad = f"{dal}#{tur}"
    y = [{**x, "dal": ad, "is": dal, "dal_kaydi": ad, "zaman_korundu": True}
         for x in grup]
    y.append({"dal": ad, "is": dal, "sira": 0, "dosya": None, "kusurlu": False,
              "zaman": grup[-1]["zaman"], "dal_kaydi": ad, "birlesme": True,
              "zaman_korundu": True})
    return y


def tarihce(kayit, k):
    """k islemede bir ana dala donen dal duzeni. k=0: dal hic acilmaz."""
    sirali = sorted(kayit, key=lambda y: y["zaman"])
    if k == 0:
        return [{**x, "is": x["dal"], "dal_kaydi": None, "zaman_korundu": True}
                for x in sirali]
    t, tampon, tur = [], {d: [] for d in DALLAR}, {d: 0 for d in DALLAR}
    for x in sirali:
        tampon[x["dal"]].append(x)
        if len(tampon[x["dal"]]) == k:
            tur[x["dal"]] += 1
            t.extend(bosalt(tampon[x["dal"]], x["dal"], tur[x["dal"]]))
            tampon[x["dal"]] = []
    for d in DALLAR:
        if tampon[d]:
            tur[d] += 1
            t.extend(bosalt(tampon[d], d, tur[d]))
    return t


def s1_gruplama(t):
    return all(x.get("dal_kaydi") for x in t if not x.get("birlesme"))


def s2_kusur(t):
    kusurlu = [x for x in t if x["kusurlu"]]
    return len(kusurlu) == 1 and not kusurlu[0].get("sikisik")


def s3_sira(t):
    return all(x.get("zaman_korundu") for x in t)


def s4_dosya(t):
    return all(isinstance(x["dosya"], str) or x.get("birlesme") for x in t)


def s5_kapsam(t):
    yerler = {}
    for i, x in enumerate(t):
        if x.get("birlesme"):
            continue
        yerler.setdefault(x["dal"], []).append(i)
    return all(y[-1] - y[0] == len(y) - 1 for y in yerler.values())


def s6_cakisma(t):
    return any("secilen" in x for x in t)


SORULAR = (("özellik gruplaması", s1_gruplama), ("kusurun yalıtımı", s2_kusur),
           ("gerçek sıra", s3_sira), ("dosya izi", s4_dosya),
           ("dalın bütünlüğü", s5_kapsam), ("çakışma kararı", s6_cakisma))


def giris_ani(kayit, k, dal, sira):
    """O islemenin ana dala girdigi an."""
    grup = [x for x in kayit if x["dal"] == dal]
    if k == 0:
        return grup[sira - 1]["zaman"]
    return grup[min(((sira - 1) // k + 1) * k, len(grup)) - 1]["zaman"]


def tur_baslangici(kayit, k, dal, sira):
    """O islemenin bulundugu turun dalinin acildigi an."""
    grup = [x for x in kayit if x["dal"] == dal]
    if k == 0:
        return grup[sira - 1]["zaman"]
    return grup[((sira - 1) // k) * k]["zaman"]


kayit = gelisim()
dokunus = [(k["dal"], k["sira"]) for k in kayit if k["dosya"] == ORTAK_DOSYA]
onceki, sonraki = dokunus[0], dokunus[1]

print(f"gerçek gelişim: {len(kayit)} işleme | {ORTAK_DOSYA} dosyasına dokunan: "
      f"{dokunus}")
print()
print(f"{'dal düzeni':<22s} {'işleme':>6s} {'kapanış':>7s} {'dal kaydı':>9s}"
      f" {'iş başına dal':>13s} {'yanıtlanan':>10s}")
for k, ad in DUZENLER:
    t = tarihce(kayit, k)
    kap = sum(1 for x in t if x.get("birlesme"))
    kayitlar = {x["dal_kaydi"] for x in t if x["dal_kaydi"]}
    print(f"{ad:<22s} {len(t):6d} {kap:7d} {len(kayitlar):9d}"
          f" {(len(kayitlar) / len(DALLAR) if kayitlar else 0):13.1f}"
          f" {sum(s(t) for _, s in SORULAR):10d}")
print()
print(f"{'dal düzeni':<22s} {'ayrışma':>7s} {'önceki dokunuş girer':>20s}"
      f" {'sonraki dal açılır':>18s} {'paralel':>7s}")
for k, ad in DUZENLER:
    girer = giris_ani(kayit, k, onceki[0], onceki[1])
    acilir = tur_baslangici(kayit, k, sonraki[0], sonraki[1])
    print(f"{ad:<22s} {k:7d} {girer:20d} {acilir:18d}"
          f" {('evet' if girer > acilir else 'hayır'):>7s}")
```

```
gerçek gelişim: 12 işleme | ayar.py dosyasına dokunan: [('olcum', 3), ('rapor', 3)]

dal düzeni             işleme kapanış dal kaydı iş başına dal yanıtlanan
dal açılmıyor              12       0         0           0.0          3
her işlemede dönüş         24      12        12           4.0          5
iki işlemede dönüş         18       6         6           2.0          5
dört işlemede dönüş        15       3         3           1.0          5

dal düzeni             ayrışma önceki dokunuş girer sonraki dal açılır paralel
dal açılmıyor                0                   17                 19   hayır
her işlemede dönüş           1                   17                 19   hayır
iki işlemede dönüş           2                   23                 19    evet
dört işlemede dönüş          4                   23                  4    evet
```

## Tarihçeye Ne Bıraktılar

Üst tablonun son sütunu ilk bakışta şaşırtıcıdır: üç dal düzeni de altı sorunun **5**'ini
yanıtlıyor. Dört işlemede dönen düzen birinci dersteki birleştirme işlemesi biçiminin
kendisidir ve beklenen sayıyı veriyor; ama her işlemede dönen düzen de, iki işlemede dönen
düzen de aynı **5**'i veriyor. **Altı soru dal düzenlerini birbirinden ayırmıyor.** Dal
açılmayan düzen ise **3**'te kalıyor — dal kaydı hiç yazılmadığı için özellik gruplaması ve
dalın bütünlüğü düşüyor, sonuç ileri sarmanın sonucuna eşitleniyor.

Düzenleri ayıran şey soldaki sütunlardır. Aynı on iki işlemelik gelişim, dört işlemede
dönen düzende **15**, iki işlemede dönende **18**, her işlemede dönende **24** işleme
bırakıyor. Kapanış işlemesi sayısı sırasıyla **3**, **6** ve **12**. Son düzende tarihçenin
**yarısı** kapanış işlemesidir: yirmi dört kayıttan on ikisi hiçbir dosyaya dokunmaz. Bu,
önceki derste ölçülen **3/12**'lik kapanış bedelinin dört katıdır ve dal sayısıyla
doğrusal büyür — dönüş sıklığı iki katına çıktığında kapanış sayısı da iki katına çıkar.

Dal kaydı sütunu ikinci maliyeti veriyor. Her işlemede dönen düzende **12** ayrı dal kaydı
var ve üç işe bölündüğünde iş başına **4.0** dal düşüyor. Bu sayı, tarihçenin bir işi tek
bir kayıtta göstermediği anlamına gelir: özellik gruplaması sorusu **evet** der ama
gösterdiği grup bir iş değil, bir **turdur**. Soru dal düzeyinde yanıtlanır ve dal, işten
küçülmüştür.

Buradan bir uyarı çıkar. Altı soru bir tümleştirme biçimini ölçmek için kurulmuştu ve o işi
yapar; bir dal **düzenini** ölçmek için tek başına yetmez. Düzenin maliyeti soruların
dışında, kapanış oranı ile iş başına dal sayısında durur. Ölçünün nereye kadar geçerli
olduğunu bilmek, ölçünün kendisi kadar önemlidir.

## Ayrışmanın Ödettiği

Alt tablo öbür yöne bakıyor. `ayar.py` dosyasına dokunan iki işleme her düzende aynı iki
işlemedir; değişen, ikincisinin dalı açıldığında birincisinin ana dalda olup olmadığıdır.

Dört işlemede dönen düzende `olcum` dalının üçüncü işlemesi ana dala **23** anında giriyor,
`rapor` dalı ise **4** anında açılmış durumda. İkinci dal çok önce açıldığı için birincinin
değişikliğini hiç görmüyor: iki dokunuş **paralel** ve çakışma doğuyor. İki işlemede dönen
düzende ayrışma yarıya iniyor ama sonuç değişmiyor; giriş anı **23**, dal açılışı **19** ve
dokunuşlar yine paralel.

Her işlemede dönen düzende tablo dönüyor. `olcum` dalının üçüncü işlemesi yazıldığı anda,
**17**'de, ana dala giriyor; `rapor` dalının o turu ise **19**'da açılıyor. İkinci dal
birincinin değişikliğini **taban olarak** görüyor ve **paralel hayır**. Aynı dosyaya
dokunulmasına rağmen ortada çözülecek bir çakışma yok. Dal açılmayan düzende ayrışma
**0**'dır ve sonuç aynıdır.

Örüntü şudur: **ayrışma penceresi kapandığında çakışma doğmaz.** Kısa ömürlü dalın satın
aldığı şey çözülmesi kolay çakışmalar değil, hiç doğmayan çakışmalardır. Ödediği şey ise
üst tablodadır: on iki kapanış işlemesi ve iş başına dört dal kaydı.

Bir üçüncü maliyet ölçümün dışında kalır ve söylenmesi gerekir. Ayrışmayı düşük tutmak,
dalın hızla ana dala dönebilmesine bağlıdır; dönüş bir onay adımından geçiyorsa ayrışma
o adımın süresi kadar uzar. Yani dal ömrü yalnız bir yazma alışkanlığı değil, bir
inceleme hızıdır. İnceleme akışının kendisi bu kursun sonraki konusunda mekanik olarak
kurulur, inceleme ekseni ve kültürü ise ayrı bir kursun konusudur.

İki tablo birlikte okunduğunda strateji kararı yerine oturur. Uzun ömürlü dal tarihçeyi
kısa ve iş düzeyinde okunur tutar, ayrışmayı ve çakışmayı biriktirir. Kısa ömürlü dal
çakışmayı ortadan kaldırır, tarihçeyi kapanış işlemeleriyle şişirir ve işi turlara böler.
İkisinin arasında bir doğru nokta yoktur; hangi maliyetin ödenebilir olduğu ekibin
sorusudur. Ölçüm yalnız iki maliyetin **aynı anda azaltılamayacağını** gösterir.

## Özet

- Dal stratejilerinin farkı tek bir büyüklüğe iner: bir dalın ana dala dönmeden önce
  biriktirdiği işleme sayısı. Bu sayı hem tarihçenin boyunu hem ayrışmayı belirler.
- Aynı on iki işlemelik gelişim dal açılmayan düzende **12**, dört işlemede dönende **15**,
  iki işlemede dönende **18**, her işlemede dönende **24** işleme bırakır; kapanış sayıları
  **0**, **3**, **6** ve **12**'dir.
- Üç dal düzeni de altı sorunun **5**'ini yanıtlar: **altı soru dal düzenlerini
  ayırmaz**. Dal açılmayan düzen **3**'te kalır.
- Her işlemede dönen düzende iş başına **4.0** dal kaydı düşer; özellik gruplaması evet der
  ama gösterdiği grup bir iş değil bir turdur.
- Çakışma yalnız paralel dokunuşlarda doğar; ayrışma **1** ya da **0** olduğunda ikinci dal
  birincinin değişikliğini taban olarak görür ve çakışma hiç doğmaz.

## Sonraki Adım

Bu konunun kurduğu her şey — dört tümleştirme biçimi, çakışmanın çözümü, dal ömrü ve
strateji kararı — **tek bir depo** varsayımıyla ölçüldü. Tarihçe bir yerde duruyordu,
birleşmeler orada yapılıyordu, dal kayıtları oraya yazılıyordu.

Gerçek bir ekipte bu varsayım geçerli değildir: tarihçe **birden çok kopyada** yaşar. Her
kişinin kendi deposu vardır, kopyalar birbirinden ayrı ilerler ve ölçülen bütün sorular bir
kez daha sorulur — bu kez "hangi kopyada" diye. Sonraki konu buradan başlar ve önce en
temel soruyu yanıtlar: bir depo başka bir depoyu nasıl tanır, birden çok kopya nasıl
adlandırılır ve ayrı tutulur.
