---
title: 'Yama Tabanlı Katkı'
source: 'https://academia.sh/tr/kurslar/dallanma-ve-isbirligi/yama-tabanli-katki'
course: 'Dallanma ve İşbirliği'
language: tr
updated: '2026-08-17T18:10:45+00:00'
license: 'CC BY-SA 4.0'
---

# Yama Tabanlı Katkı

Yama bir metin dosyasıdır ve çizgeyi değil değişikliği kodlar: tarihçeyle itme 15 işlemede 5 soru, posta biçimli seri 12 işlemede 4, düz fark serisi 12 işlemede 3, tek düz fark 1 işlemede 1 soru bırakır ve düz farkta yazarı korunan işleme 0'dır.

Önceki dersin akışı bir depo platformu varsaydı: ortak bir adres, bir tartışma alanı ve
tümleştirme kararını verecek bir yetki. Katkının bunların hiçbiri olmadan gittiği bir biçim
daha vardır ve sürüm kontrolünün en eski katkı biçimi budur: değişikliğin **dosya olarak**
gönderilmesi.

Yama, bir depoya değil bir posta kutusuna sığar. Bu dersin sorusu yamanın nasıl üretildiği
değil — üretimi iki komuttan ibarettir. Soru şudur: yama karşı tarafa **neyi taşır**, neyi
taşımaz, ve taşımadığı alan altı sorunun neresine düşer?

## İki Yama Biçimi

**Yama (patch)**, bir değişikliğin metin olarak kodlanmış hâlidir ve iki ayrı biçimi vardır.
Birincisi **düz farktır**: yalnız değişiklik metnini taşır, üstveri taşımaz.

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

git diff yukari/ana..olcum > olcum.patch
git apply --check olcum.patch
git apply olcum.patch
```

`--check` seçeneği yamayı uygulamadan sınar ve çalışma alanına dokunmaz. Uygulama başarılı
olduğunda değişiklikler çalışma alanına yazılır ve **hiçbir işleme oluşmaz**: işlemeyi
uygulayan yazar, kendi adıyla ve kendi zamanıyla.

İkincisi **posta biçimli yama serisidir**: her işleme için bir dosya üretilir ve dosyanın
başında bir posta başlığı durur.

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

git format-patch yukari/ana..olcum -o yamalar/
git am --3way yamalar/0001-olcum-esigini-yapilandirmadan-oku.patch

From <işleme kimliği> Mon Sep 17 00:00:00 2001
From: yazan <yazan@ornek.test>
Date: <yazar tarihi>
Subject: [PATCH 1/4] Ölçüm eşiğini yapılandırmadan oku

Eşik değeri betiğe gömülüydü; ölçüm noktası değiştiğinde betiği
düzenlemek gerekiyordu.
---
 olcum.py | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
```

Başlıktaki üç alan doğrudan işlemeye geçer: yazar, yazar tarihi ve mesaj. `git am` her dosya
için bir işleme yazar ve bu alanları yerelden değil **dosyadan** okur. `--3way` seçeneği,
yama doğrudan uymadığında ortak tabana bakarak üç yollu birleştirme dener; çakışma çıkarsa
karar yine elle verilir.

## Yamanın Taşıyamadığı

İki biçimin de taşıyamadığı bir alan sınıfı var ve nedeni yapısaldır. Yama bir **metin
dosyasıdır** ve bir değişikliği kodlar; tarihçe ise bir **çizgedir** ve metin dosyası kenar
taşımaz. Bu yüzden yamanın karşı tarafta ürettiği işleme her zaman **yeni kimliklidir**,
öncül bağı uygulandığı yerin ucudur ve dal kaydı hiç geçmez — yamada dal diye bir şey yoktur,
yalnız dosya vardır.

Ölçüm bu nedenle tarihçeyi taşınan üstveri kümesinden **türetir**; biçimleri elle betimlemez.

## Ölçümün Varsayımları

- **UD25** — Aynı on iki işlemelik gelişim dört ayrı katkı biçimiyle karşı tarafa taşınır;
  üretilen kod dördünde de aynıdır ve ölçülen tek şey karşı tarafta kalan **üstveridir**.
- **UD26** — Her biçim bir **taşınan üstveri kümesiyle** tanımlanır; karşı taraftaki tarihçe
  bu kümeden hesaplanır, elle yazılmaz.
- **UD27** — Posta biçimli seri yazarı, yazar zamanını ve mesajı taşır; dal kaydını ve öncül
  bağını taşımaz.
- **UD28** — Düz fark serisi yalnız değişiklik metnini ve mesajı taşır; yazar ve zaman
  uygulama anında yerelden yazılır ve bu ölçümde "taşımaz" sayılır.
- **UD29** — Tek düz fark, on iki işlemenin farkını tek dosyada toplar ve karşı tarafta tek
  işleme olur; sıkıştırmanın en uç biçimidir.
- **UD30** — "Yazarı korunan" sütunu, karşı tarafta yazar alanı özgün katkıcıyı gösteren
  işlemeleri sayar; birleştirme işlemeleri tümleştirenin adına yazıldığı için sayıma girmez.

## Ölçüm

```python
"""Yama tabanlı katkı: taşınan üstveri ve taşınmayanın bedeli.

Bölüm 1 - dört katkı biçiminin taşıdığı üstveri alanları.
Bölüm 2 - aynı biçimlerin bıraktığı tarihçe ve yanıtladığı soru.
"""
TOHUM = 20260813
DALLAR = ("olcum", "rapor", "kimlik")
DOSYALAR = {"olcum": "olcum.py", "rapor": "rapor.py", "kimlik": "kimlik.py"}
KUSURLU = ("rapor", 2)
ORTAK_DOSYA = "ayar.py"
USTVERI = ("yazar", "yazar zamanı", "konu ve gövde", "dal kaydı", "öncül bağı")
TASINAN = {"tarihçeyle itme": set(USTVERI),
           "posta biçimli seri": {"yazar", "yazar zamanı", "konu ve gövde"},
           "düz fark serisi": {"konu ve gövde"},
           "tek düz fark": set()}


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

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


def gelisim():
    """Gerçek gelişim: üç dal, dörder işleme, biri kusuru getiriyor."""
    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 uygula(kayit, tur):
    """Katkının karşı tarafta bıraktığı tarihçe: taşınan üstveriden türer."""
    tasinan = TASINAN[tur]
    if tur == "tarihçeyle itme":
        t = []
        for dal in DALLAR:
            for k in [x for x in kayit if x["dal"] == dal]:
                t.append({**k, "dal_kaydi": dal, "zaman_korundu": True,
                          "yazar_korundu": True})
            t.append({"dal": dal, "sira": 0, "dosya": None, "kusurlu": False,
                      "zaman": max(x["zaman"] for x in kayit if x["dal"] == dal),
                      "dal_kaydi": dal, "birlesme": True, "zaman_korundu": True,
                      "yazar_korundu": False})
        return t
    if tur == "tek düz fark":
        return [{"dal": None, "sira": 0,
                 "dosya": sorted({x["dosya"] for x in kayit}),
                 "kusurlu": any(x["kusurlu"] for x in kayit),
                 "zaman": max(x["zaman"] for x in kayit), "dal_kaydi": None,
                 "zaman_korundu": False, "yazar_korundu": False,
                 "sikisik": len(kayit)}]
    return [{**k, "dal_kaydi": k["dal"] if "dal kaydı" in tasinan else None,
             "zaman_korundu": "yazar zamanı" in tasinan,
             "yazar_korundu": "yazar" in tasinan}
            for dal in DALLAR for k in kayit if k["dal"] == dal]


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


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


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


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


def s5(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(t):
    return any("secilen" in x for x in t)


SORULAR = (("özellik gruplaması", s1), ("kusurun yalıtımı", s2), ("gerçek sıra", s3),
           ("dosya izi", s4), ("dalın bütünlüğü", s5), ("çakışma kararı", s6))

kayit = gelisim()
print(f"gerçek gelişim {len(kayit)} işleme, {len(DALLAR)} dal, "
      f"kusurlu işleme {sum(k['kusurlu'] for k in kayit)}")
print()
print("üstveri alanı  " + "".join(f"{ad:>20s}" for ad in TASINAN))
for alan in USTVERI:
    print(f"  {alan:13s}" + "".join(f"{('taşır' if alan in TASINAN[t] else 'taşımaz'):>20s}"
                                    for t in TASINAN))
print()
print("katkı biçimi          işleme  yazarı korunan  ayrı okunabilir  yanıtlanan  kaybolan")
for tur in TASINAN:
    t = uygula(kayit, tur)
    ayri = sum(1 for x in t if not x.get("birlesme") and not x.get("sikisik"))
    print(f"  {tur:20s} {len(t):6d} {sum(x['yazar_korundu'] for x in t):15d}"
          f" {ayri:16d} {sum(f(t) for _, f in SORULAR):11d} {len(kayit) - ayri:9d}")
print()
print("yanıtlanamayan sorular:")
for tur in TASINAN:
    t = uygula(kayit, tur)
    print(f"  {tur:20s} " + ", ".join(ad for ad, f in SORULAR if not f(t)))
```

```
gerçek gelişim 12 işleme, 3 dal, kusurlu işleme 1

üstveri alanı       tarihçeyle itme  posta biçimli seri     düz fark serisi        tek düz fark
  yazar                       taşır               taşır             taşımaz             taşımaz
  yazar zamanı                taşır               taşır             taşımaz             taşımaz
  konu ve gövde               taşır               taşır               taşır             taşımaz
  dal kaydı                   taşır             taşımaz             taşımaz             taşımaz
  öncül bağı                  taşır             taşımaz             taşımaz             taşımaz

katkı biçimi          işleme  yazarı korunan  ayrı okunabilir  yanıtlanan  kaybolan
  tarihçeyle itme          15              12               12           5         0
  posta biçimli seri       12              12               12           4         0
  düz fark serisi          12               0               12           3         0
  tek düz fark              1               0                0           1        12

yanıtlanamayan sorular:
  tarihçeyle itme      çakışma kararı
  posta biçimli seri   özellik gruplaması, çakışma kararı
  düz fark serisi      özellik gruplaması, gerçek sıra, çakışma kararı
  tek düz fark         özellik gruplaması, kusurun yalıtımı, gerçek sıra, dosya izi, çakışma kararı
```

## Basamakların Okunması

Alt tablo dört basamak veriyor ve her basamağın bir üstveri karşılığı var.

**Tarihçeyle itme** on beş işleme ve **5** soru bırakıyor; bu ölçüt satırıdır, bütün alanlar
geçmiştir.

**Posta biçimli seri** on iki işleme bırakıyor ve **4** soru yanıtlıyor. Düşen tek soru
**özellik gruplaması**; nedeni üst tablonun dördüncü satırında yazılı, dal kaydı taşınmıyor.
Yazar ve zaman taşındığı için "gerçek sıra" ayakta kalıyor.

**Düz fark serisi** de on iki işleme bırakıyor ama **3** soru yanıtlıyor. Fark tek bir alandan
geliyor: yazar zamanı taşınmadığı için bütün işlemeler uygulama anının zamanını taşıyor ve
**gerçek sıra** okunamıyor. Aynı sayıdaki işleme, tek bir üstveri alanı yüzünden bir soru daha
az yanıtlıyor.

**Tek düz fark** on iki işlemeyi bire indiriyor, **1** soru yanıtlıyor, kaybolan işleme
**12**. Kursta ölçülen en düşük değer budur; sıkıştırma on iki işlemeyi üçe indirip **2**
yanıtlıyordu. Altıncı soru ise dört satırda da yanıtsız — katkının hangi taşıma aracıyla
gittiği bunu değiştirmiyor.

## Ölçünün Görmediği Alan

Üçüncü satır kursun kendi ölçüsüne dönük bir uyarı taşıyor. Düz fark serisi ile posta biçimli
seri arasında **yazarı korunan** sütunu **12**'den **0**'a düşüyor: on iki işlemenin hiçbiri
artık yazanı göstermiyor, hepsi uygulayan kişinin adına yazılmış. Yanıtlanan soru ise yalnız
**1** düşüyor ve düşen soru yazarla ilgili değil.

Nedeni açıktır: **altı sorunun hiçbiri yazarı sormaz.** Sorular gruplamayı, yalıtımı, sırayı,
dosya izini, dal bütünlüğünü ve çakışma kararını sorar; katkının kime ait olduğu kümede
yoktur, dolayısıyla ölçü onu göremez. Bu bir ölçü kusuru değil, ölçünün **kapsamının**
bildirimidir. Katkı sahipliği ve imza o pencerenin dışındadır ve düz fark serisi bunları
sessizce siler.

## Özet

- Yama bir metin dosyasıdır ve değişikliği kodlar; çizgeyi kodlamadığı için işleme kimliği,
  öncül bağı ve dal kaydı hiçbir yama biçiminde taşınmaz. Posta biçimli seri yazarı, zamanı
  ve mesajı taşır; düz fark yalnız değişiklik metnini taşır.
- Dört katkı biçimi karşı tarafa **15**, **12**, **12** ve **1** işleme bırakır ve
  sırasıyla **5**, **4**, **3** ve **1** soru yanıtlar.
- Posta biçimli seri ile düz fark serisi aynı sayıda işleme bırakır; aradaki bir soruluk fark
  yalnız **yazar zamanı** alanının taşınmamasından gelir.
- Yazarı korunan işleme sayısı **12**'den **0**'a düştüğünde yanıtlanan soru yalnız bir
  azalır: altı sorunun hiçbiri yazarı sormaz ve bu, ölçünün kapsam sınırıdır.

## Kurs Kapanışı

Kurs tek bir ölçüyle yürüdü: bir tümleştirme biçiminin sayısı, ürettiği kod değil, bıraktığı
tarihçenin yanıtlayabildiği **soru sayısıdır**. On beş ders bu ölçüyü ayrı yerlere uyguladı.

| ders | ölçülen | yanıtlanan soru ya da kayıp |
|---|---|---|
| Dal Kavramı | dallanmanın maliyeti | 0 yeni işleme ve 123 bayt başvuru; kopya modeli aynı işi 12.000 dosya kopyalayarak yapar |
| Dal Oluşturma ve Geçiş | geçişin elde kalan değişikliğe yaptığı | 12 durumun 3'ü taşınır, 5'i engellenir, 4'ü geride kalır; sessiz kayıp 0 |
| Dal Adlandırma | ad düzeninin birinci soruya katkısı | 8 bileşimin 3'ünde grup okunur; kayıt tutmayan biçimde katkı 0 |
| Ayrık HEAD Durumu | erişilemeyen işlemenin tarihçeye maliyeti | 15 kayıt 13'e, yanıt 5'ten 4'e iner; üç sayım sorgusunun 3'ü de eksik yanıtlanır ve tarihçe bunu bildirmez |
| İleri Sarma ve Birleştirme İşlemesi | iki birleşme biçiminin bıraktığı tarihçe | 15 işleme / 5 soru ve 12 işleme / 3 soru; farkı gruplama ile dal bütünlüğü yaratır |
| Çakışma Çözümü | çözümün tarihçeye geçip geçmediği | dört biçimin dördü de altıncı soruyu yanıtlamaz, 0/4; gerekçe mesaja yazılırsa 15 işlemenin 1'i onu taşır |
| Yeniden Temellendirme | doğrusallaştırmanın bıraktığı tarihçe | 12 işleme / 3 soru; ileri sarmayla toplam eşit, kayıp ayrı, fark 1/6 |
| Kiraz Toplama | aynı değişikliğin iki yerde durması | dosya izi evet kalır, dokunan işleme 3'ten 4'e çıkar; kusurlu kopyada yanıt 5'ten 4'e iner |
| Birleştirme Stratejileri | dört biçim yan yana | 15/12/3/12 işleme ve 5/3/2/3 soru; sıkıştırmada kaybolan 12 |
| Dal Stratejileri | dal ömrünün tarihçeye yazdırdığı | 12, 15, 18 ve 24 işleme; üç dal düzeni de 5 soru yanıtlar — altı soru dal düzenlerini ayırmaz |
| Uzak Depo Tanımlama | tanımlamanın tarihçeye eklediği | üç kopya 5/10/15 işleme ve 4/5/5 soru; iki tanımdan sonra yerel 5 işleme / 4 soru |
| Getirme, Çekme ve İtme | üç işlemin değiştirdiği tarihçe | getirme dalı 5'te bırakır, çekme 16'ya ve 5 soruya taşır, itme karşı tarafı 10'dan 16'ya değiştirir |
| Çatallama ve Klonlama | yukarı deponun yanıtlayabildiği | 15/5, 12/3 ve 3/2; sıkıştırmada 3 soru yalnız çatal deposunda kalır |
| Değişiklik İsteği Akışı | akışın seçtiği biçimin bıraktığı | 5/3/2/3 soru; 11 kararın 7'si tarihçeye hiç girmez, sıkıştırmada yazılan 4'ü de okunmaz olur |
| Yama Tabanlı Katkı | yamanın taşıdığı ve taşımadığı üstveri | 15/5, 12/4, 12/3 ve 1/1; düz farkta yazarı korunan 0 ve altı soru bunu hiç sormaz |

Tablodan üç okuma çıkar. **Birincisi:** okunaklılık ile yanıtlanabilirlik ters yönde hareket
eder — en temiz tarihçeler en az soru yanıtlayanlardır ve tarihçeyi temizlemek bilgi siler.
**İkincisi:** altıncı soru hiçbir satırda yanıtlanmaz; çakışmanın nasıl çözüldüğü kaydın
tanımı gereği kayıtta yoktur ve tek çare gerekçeyi işleme mesajına yazmaktır. **Üçüncüsü:**
kayıp iki ayrı kaynaktan gelir. Biçim kaybı bilgiyi siler ve geri alınamaz; kapsam kaybı
yalnız bir kopyanın eksikliğidir ve getirmeyle kapanır.

Kurs boyunca tarihçe hep **okundu**: sorular sorulmuş, yanıtlar sayılmış, biçimlerin bıraktığı
kayıt olduğu gibi kabul edilmiştir. Sonraki kurs — İleri Git — aynı kaydı **yeniden yazma**
araçlarını ele alır: etkileşimli yeniden temellendirme, toplu tarihçe dönüşümü, zorlayıcı itme
disiplini ve kaybolan işlemeleri kurtaran referans günlüğü. Ayrım baştan konmalıdır:
**tarihçeyi okumak ile yeniden yazmak ayrı işlerdir.** Okumak hiçbir şeyi değiştirmez; yeniden
yazmak, bu kursta sayılan soruların yanıtlarını kalıcı olarak değiştirebilir. Bu kursun
bıraktığı ölçü, oradaki her aracın bedelini hesaplamakta kullanılacak birimdir.
