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

# Dal Kavramı

Dal bir işaretçidir: on iki işlemelik bir kurguda üç dalın açılışı sıfır yeni işleme ve 123 bayt başvuru yazar, kopya modeli aynı ağacı dört bin dosyada on iki bin dosya kopyalarken işaretçi modelinin maliyeti sabit kalır.

Sürüm Kontrolüne Giriş kursu tarihçeyi tek bir çizgi olarak kurdu. Çalışma dizini, hazırlık
alanı ve işleme birbirini izledi; her yeni işleme bir öncekini gösterdi ve tarihçe okunurken
sıra hep aynı kaldı — en yeniden en eskiye doğru tek bir yol. O kursta tarihçe **doğrusaldı
ve tek yazarlıydı**: bir kişi, bir sıra, bir çizgi.

Birden çok kişi aynı depoda çalıştığında bu varsayım düşer. İki kişi aynı işlemeden başlayıp
ayrı yönlere gider ve tarihçe artık bir çizgi değil bir **çatallanmadır**. Bu kursun sorusu
çatallanmanın nasıl açıldığı değildir — açmak ucuzdur ve bu ders tam olarak ne kadar ucuz
olduğunu ölçer. Asıl soru çatallanmanın nasıl **kapatıldığıdır**, çünkü kapatma biçimi
tarihçenin sonradan hangi soruları yanıtlayabileceğini belirler.

## Kursun Ölçü Ekseni

Kurs boyunca tek bir kurgu kullanılır. Üç kişi aynı depoda üç ayrı işe başlıyor: `olcum`,
`rapor` ve `kimlik`. Her biri dört işleme yapıyor ve her işleme kendi dosyasına dokunuyor;
üçüncü adımda ikisi birden `ayar.py` dosyasına dokunuyor. `rapor` işinin ikinci işlemesi bir
kusur getiriyor. Gerçek gelişim **on iki işlemedir** ve sırası bilinir, çünkü kurguyu biz
yazdık.

Bu on iki işleme dört ayrı **tümleştirme biçimiyle (integration format)** ana dala alınabilir:
birleştirme işlemesi, yeniden temellendirme, sıkıştırma ve ileri sarma. Dördü de aynı **kodu**
üretir. Ürettikleri **tarihçe** ayrıdır ve kurs bu farkı tek bir şeyle ölçer: tarihçeye altı
soru sorulur ve kaçını yanıtlayabildiği sayılır. Bunlar kursun **yanıtlanabilir soruları
(answerable questions)** olarak anılır ve tanımları kurs boyunca değişmez.

1. **Özellik gruplaması** — hangi işlemeler hangi işe ait?
2. **Kusurun yalıtımı** — kusuru getiren işleme tek başına bulunabiliyor mu?
3. **Gerçek sıra** — işler hangi sırayla geliştirildi?
4. **Dosya izi** — bir dosyaya dokunan her işleme ayrı ayrı bulunabiliyor mu?
5. **Dalın bütünlüğü** — bir dalın işlemeleri bir arada mı duruyor?
6. **Çakışma kararı** — çakışma nerede çözüldü ve hangi taraf seçildi?

Bu ders soruların hiçbirini yanıtlamaz. Ölçtüğü şey daha önceki bir adımdır: çatallanmayı
açmanın maliyeti.

## Dal Bir İşaretçidir

Depo Oluşturma ve Yapılandırma dersinde **başvuru (ref)** tanıtılmıştı: bir ada bağlanmış
işleme kimliği. Dal bundan başka bir şey değildir. `refs/heads` altındaki bir başvurunun
içeriği kırk onaltılık basamaklık bir kimlik ve bir satır sonudur; toplam kırk bir bayt.

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

$ git branch olcum
$ git branch
* ana
  olcum
$ git rev-parse olcum
3f1a9c4e6b2d8057a41c9e3b7d604f2a8c15be93
$ git symbolic-ref HEAD
refs/heads/ana
```

Başvurular dosya olarak da paketlenmiş biçimde de tutulabilir, bu yüzden `refs/heads/olcum`
dosyasının varlığına değil `git rev-parse` çıktısına güvenilir. Kimliğin kendisi depoya
özeldir; buradaki değer kurgudur ve kendi deponuzda başka bir değer görürsünüz. Sabit olan
başvurunun **yapısıdır**: bir ad, bir kimlik.

`HEAD` ise bir işlemeyi değil bir **başvuruyu** gösterir; buna simgesel başvuru denir. Zincir
üç halkalıdır: `HEAD` bir dal adını, dal adı bir işleme kimliğini, işleme de kendi öncülünü
gösterir. Bir dalda işleme yapmak yalnız orta halkayı değiştirir — dal başvurusundaki kimlik
yeni işlemenin kimliğiyle değiştirilir, kırk bir bayt yeniden yazılır. `HEAD` yerinde kalır,
çünkü hâlâ aynı dalı göstermektedir.

Etiketleme dersindeki hafif etiket de `refs` altında bir kimlik tutar; aradaki fark tek
kelimeyle **hareketliliktir**. Etiket bir işlemeye bir kez bağlanır ve kendiliğinden hiçbir
yere gitmez; dal başvurusu her işlemede yeniden yazılır ve dalın ucunu izler. Aynı veri
yapısının iki kullanımıdır: biri bir noktayı sabitlemek, öteki bir noktayı sürüklemek için.
Bu yüzden bir etiketin üstünde çalışılmaz, bir dalın üstünde çalışılır — ve `HEAD` bir dal
adını gösterdiği sürece yapılan her işleme bir yere **bağlanır**. `HEAD`in bir dal adı yerine
doğrudan bir işleme kimliğini gösterdiği durum ayrı bir addır ve bu konunun dördüncü dersinde
ele alınır.

Bunun doğrudan bir sonucu var: **dal işlemeleri içermez.** Dal yalnız bir uç işleme gösterir
ve "dalın işlemeleri" dediğimiz şey o uçtan öncül kenarları izleyerek gidilebilen kümedir.
Tarihçeyi Okuma dersindeki **erişilebilirlik (reachability)** tanımı burada aynen geçerlidir.
İki dalın ortak öncülleri iki kümede birden bulunur ve hiçbir yere kopyalanmamıştır.

## Çatallanmanın Şekli

Tarihçeyi Okuma dersinde `git log --graph` çıktısı tek sütunluk bir çizim vermişti; o
tarihçede dallanma yoktu. Kurgunun tarihçesi üç sütunludur. Şekli komut çıktısından bağımsız
olarak çizmek daha açıktır:

```text
# tarihçenin şekli — çizim, komut çıktısı değildir

                 olcum   ->  4 işleme
                /
  taban  ------+------->  rapor   ->  4 işleme
                \
                 kimlik  ->  4 işleme
```

Üç dalın da geriye doğru izlendiğinde ulaştığı ilk ortak işlemeye **ortak taban (merge base)**
denir. Ortak taban bir işlemedir, bir dal değildir; hangi dalın ucunda durduğunuza bakılmaksızın
aynı işlemedir ve iki dal karşılaştırıldığında farkın nereden başlatılacağını belirler. Bu
kursun geri kalanı ortak tabanın üstünde çalışır: birleştirme de, yeniden temellendirme de,
"bu dalda ne var da ötekinde yok" sorusu da tabandan itibaren hesaplanır.

Dal uçları tek satırda da listelenebilir:

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

$ git branch -v
* ana     0a5f3c9 Ölçüm iskeletini ekle
  kimlik  9d4c1a7 Kimlik doğrulama adımını tamamla
  olcum   6e2d70b Ölçüm eşiğini yapılandırmaya taşı
  rapor   7c3f9d2 Rapor başlığını biçimlendir
```

Yıldız `HEAD`in hangi dalı gösterdiğini işaretler. Listedeki her satır bir ad ile bir kimlikten
ibarettir; dalın "içeriği" diye bir sütun yoktur, çünkü öyle bir şey saklanmaz.

## Kopya Modeli ve İşaretçi Modeli

Sürüm kontrolünden önceki alışkanlık, bir işi ayırmak için çalışma ağacının tamamını
kopyalamaktı. Bu **kopya modelidir** ve maliyeti açıktır: ağaçta kaç dosya varsa o kadar
kopya. Maliyet ağacın büyüklüğüyle doğru orantılı büyür, çünkü ayrılan şey ağacın kendisidir.

Kopya modelinin daha ağır bir bedeli daha vardır ve bu bedel bayt değildir. Kopyalanan ağaç
tarihçenin **dışındadır**: kopyaya bir öncül kenarı bağlanmamıştır, bir işleme kimliği yoktur
ve hiçbir başvurudan erişilmez. İki kopyayı sonradan birleştirmek, ortak tabanın ne olduğunu
bilmeyen bir karşılaştırma demektir — hangi değişikliğin yeni, hangisinin ötekinde zaten var
olduğu ancak elle çıkarılabilir. Bu kursun altı sorusundan hiçbiri kopya modeline sorulamaz,
çünkü ortada sorgulanacak bir tarihçe yoktur.

**İşaretçi modelinde** ayrılan şey ağaç değil, ağacın bir anlık görüntüsüne verilen addır.
Dosyalar zaten nesne veritabanında durur ve içerik adresli olduğu için aynı içerik iki kez
saklanmaz. Yeni dal, var olan bir işlemeye ikinci bir ad vermekten ibarettir. Ölçüm bu iki
modeli aynı kurgu üzerinde yan yana koyar.

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

- **DL1** — Kurgu üç iş ve on iki işlemedir; kâhin kurguyu biz ürettiğimiz için bilinir ve
  her işlemenin hangi işe ait olduğunu, hangi dosyaya dokunduğunu söyler.
- **DL2** — Üç dal ortak bir **taban** işlemesinden ayrılır. Taban on iki işlemenin dışındadır
  ve üç dalın da erişebildiği tek ortak işlemedir.
- **DL3** — Bir dal başvurusu kırk onaltılık basamaklık kimlik ile bir satır sonundan oluşur:
  kırk bir bayt. Ölçüm bir disk ölçümü değil, yazılan içeriğin sayımıdır.
- **DL4** — Kopya modeli dalı çalışma ağacının tam kopyası sayar ve maliyeti kopyalanan dosya
  sayısıdır. İşaretçi modeli dalı tek bir başvuru sayar ve maliyeti yazılan bayttır.
- **DL5** — Çalışma ağacı dört büyüklükle denenir: kurgunun dokunduğu dosya sayısı ve üç
  büyütme. Kurgunun işleme sayısı bu satırlarda değişmez; değişen yalnız ağacın genişliğidir.
- **DL6** — Erişilebilirlik yalnız öncül kenarlarını izler. Hiçbir başvurudan erişilemeyen bir
  işleme tarihçede sorgulanamaz; nesne veritabanında durması onu tarihçeye geri koymaz.

## Ölçüm

```python
"""Dal bir isaretcidir: dallanmanin maliyeti kopyalanan dosya degil, yazilan basvurudur."""
TOHUM = 20260813
DALLAR = ("olcum", "rapor", "kimlik")
DOSYALAR = {"olcum": "olcum.py", "rapor": "rapor.py", "kimlik": "kimlik.py"}
KUSURLU = ("rapor", 2)
ORTAK_DOSYA = "ayar.py"
BASVURU_BAYT = 40 + 1        # kirk onaltilik basamak + satir sonu


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

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


def gelisim():
    """Gercek gelisim: (dal, sira, dosya, kusurlu, zaman) beslileri."""
    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


kayit = gelisim()
agac = sorted({k["dosya"] for k in kayit})
print(f"kurgu: {len(kayit)} işleme, {len(DALLAR)} dal, dal başına "
      f"{len(kayit) // len(DALLAR)} işleme, dokunulan dosya {len(agac)} {agac}")
print(f"üç dalın açılışı: yeni işleme 0, yazılan başvuru {len(DALLAR)}, "
      f"yazılan bayt {len(DALLAR) * BASVURU_BAYT}")

print()
print("çalışma ağacı  kopya modeli: kopyalanan dosya  işaretçi modeli: yazılan bayt")
for n in (len(agac), 40, 400, 4000):
    print(f"{n:13d} {n * len(DALLAR):34d} {len(DALLAR) * BASVURU_BAYT:31d}")

print()
print("dal      ucundaki işleme  erişilen işleme  başvuru silinirse erişilemez")
for dal in DALLAR:
    grup = [k for k in kayit if k["dal"] == dal]
    print(f"  {dal:8s} {grup[-1]['sira']:12d} {1 + len(grup):16d} {len(grup):29d}")
print(f"üç başvurudan erişilen birleşim: {1 + len(kayit)} işleme "
      f"(taban + {len(kayit)}), yazılan başvuru {len(DALLAR)}")
```

```
kurgu: 12 işleme, 3 dal, dal başına 4 işleme, dokunulan dosya 4 ['ayar.py', 'kimlik.py', 'olcum.py', 'rapor.py']
üç dalın açılışı: yeni işleme 0, yazılan başvuru 3, yazılan bayt 123

çalışma ağacı  kopya modeli: kopyalanan dosya  işaretçi modeli: yazılan bayt
            4                                 12                             123
           40                                120                             123
          400                               1200                             123
         4000                              12000                             123

dal      ucundaki işleme  erişilen işleme  başvuru silinirse erişilemez
  olcum               4                5                             4
  rapor               4                5                             4
  kimlik              4                5                             4
üç başvurudan erişilen birleşim: 13 işleme (taban + 12), yazılan başvuru 3
```

## Sayıların Okunması

İlk satır kurgunun boyutunu veriyor: **12** işleme, **3** dal, dokunulan **4** dosya. İkinci
satır bu dersin ana ölçüsüdür. Üç dalın açılışı **0** yeni işleme ve **123** bayt yazıyor.
Sıfır, dallanmanın tarihçeye hiçbir şey eklemediği anlamına gelir; dal açmak bir kayıt
değildir, bir addır.

Orta tablo maliyetin nasıl davrandığını gösteriyor. Kurgunun dört dosyalık ağacında kopya
modeli **12** dosya kopyalıyor, işaretçi modeli **123** bayt yazıyor. Ağaç kırk dosyaya
çıktığında kopya modeli **120**'ye, dört yüz dosyada **1200**'e, dört bin dosyada **12000**'e
tırmanıyor. İşaretçi sütunu dört satırın dördünde de **123**. Kopya modelinin maliyeti ağacın
büyüklüğüne bağlıdır; işaretçi modelinin maliyeti **yalnız dal sayısına** bağlıdır. Aradaki
fark bin katlık bir ağaçta bin kat açılır ve bu, dallanmanın neden bir istisna değil bir
alışkanlık hâline gelebildiğinin tek nedenidir.

Alt tablo ikinci sonucu veriyor. Her dal ucundan **5** işlemeye erişiliyor: dalın kendi dördü
ve ortak taban. Üç ucun toplamı on beş değil **13**'tür, çünkü taban üç kümede birden bulunur
ve bir kez sayılır. Bir dalı **paylaşmak** da aynı ekonomiye tabidir: aynı tabana bakan
üçüncü bir ad yazmak yine kırk bir bayttır.

Kurgunun çözünürlüğü de buradan okunur. On iki işlemelik bir kümede ölçülebilen en küçük fark
**1/12**'dir; altı soruluk kümede en küçük fark **1/6**'dır. Bir dalın dört işlemesi kümenin
üçte biri, tek bir kusurlu işleme on ikide biridir. Bu çözünürlüğün altındaki farklar bu
kurguyla savunulamaz ve kurs boyunca yazılan sayılar onun üstünde tutulur.

Son sütun kursun ilerisine bakıyor. Bir dal başvurusu silinirse o daldan erişilen **4** işleme
hiçbir başvurudan erişilemez hâle gelir. İşlemeler nesne veritabanında durmayı sürdürür ama
tarihçeye sorulan altı sorunun hiçbiri onlara ulaşamaz — çünkü sorular tarihçeye sorulur ve
tarihçe, başvurulardan erişilebilen kümedir. İşaretçinin ucuzluğu ile kırılganlığı aynı
gerçeğin iki yüzüdür: kırk bir bayt yazmak kolaysa, kırk bir baytı kaybetmek de kolaydır.

## Ana Dal Ayrıcalıklı Değildir

Ölçümün doğrudan söylemediği ama sayılarından çıkan bir sonuç var. Üç dalın açılışı **123**
bayt yazıyor ve bu bayt her dal için aynı; kurgudaki `ana` dalı da `refs/heads` altında kırk
bir baytlık bir başvurudur. Araç bakımından ana dalın hiçbir ayrıcalığı yoktur: daha hızlı
okunmaz, daha güvenli tutulmaz, silinmeye karşı korunmaz. Ayrıcalık ekibin kararıdır, veri
yapısının değil.

Bunun iki pratik sonucu vardır. Birincisi, "ana dal" adının kendisi bir sözleşmedir ve depodan
depoya değişebilir; komutlar bir varsayılan ada değil, `HEAD`in gösterdiği başvuruya bakar.
İkincisi, ana dalı ayrıcalıklı kılan her koruma **depo dışında** kurulur: kimin hangi dala
yazabildiği, hangi dalın silinemeyeceği, hangi dala doğrudan işleme yapılamayacağı başvurunun
kendisinde yazılı değildir. Depo, kırk bir baytı kimin yazdığını sorgulamaz.

Bu ders için önemli olan yanı şudur: dal ucunun **hangi** işlemeyi gösterdiği bir veri
sorusudur, o dalın **ne anlama geldiği** ise bir düzen sorusudur. İkincisinin karşılığı
adlandırmadır ve kursun üçüncü dersi onu ölçer.

## Özet

- Dal, `refs/heads` altında bir ada bağlanmış işleme kimliğidir; içeriği kırk onaltılık
  basamak ve bir satır sonu, toplam kırk bir bayttır.
- `HEAD` bir işlemeyi değil bir dal başvurusunu gösterir; işleme yapmak yalnız dal
  başvurusundaki kimliği değiştirir, `HEAD` yerinde kalır.
- Dal işlemeleri içermez; "dalın işlemeleri" dal ucundan öncül kenarları izlenerek erişilen
  kümedir ve ortak öncüller kopyalanmadan iki kümede birden bulunur.
- Üç dalın açılışı **0** yeni işleme ve **123** bayt yazar; kopya modeli aynı işi dört
  dosyalık ağaçta **12**, dört bin dosyalık ağaçta **12000** dosya kopyalayarak yapar.
- Bir dal ucundan **5**, üç ucun birleşiminden **13** işlemeye erişilir; başvuru silinirse o
  daldan erişilen **4** işleme tarihçenin dışına düşer.

## Sonraki Adım

Dal açmak bir addır ve maliyeti ölçüldü. Ama ad yazıldığı anda çalışma ağacı hâlâ eski dalın
içeriğini taşır; dala **geçmek** ayrı bir işlemdir ve çalışma dizini ile hazırlık alanının
yeni dala uyarlanmasını gerektirir. O sırada elde işlenmemiş bir değişiklik varsa bir karar
verilmek zorundadır: değişiklik geçişle birlikte taşınacak mı, taşınamıyorsa geçiş
engellenecek mi. Sonraki ders dal oluşturma ile geçişi ayırır ve on iki durum üzerinde hangi
değişikliğin taşındığını, hangisinin engellendiğini, hangisinin geride kaldığını sayar.
