---
title: 'Çakışma Çözümü'
source: 'https://academia.sh/tr/kurslar/dallanma-ve-isbirligi/cakisma-cozumu'
course: 'Dallanma ve İşbirliği'
language: tr
updated: '2026-08-17T18:10:44+00:00'
license: 'CC BY-SA 4.0'
---

# Çakışma Çözümü

Araç iki tarafı birleştiremediğinde dosyaya çakışma işaretleri yazar; çözüm elle verilir ama dört tümleştirme biçiminin dördü de seçilen tarafı kaydetmez, çözümün gerekçesi işleme mesajına yazılmazsa hiçbir yerde durmaz.

Önceki dersin ölçümünde `olcum` ile `rapor` dalları üçüncü adımda aynı dosyaya dokundu.
İki tümleştirme biçimi de bu dosyayı doğru sonuçla ana dala aldı, ama iki tarihçe de
çakışmanın **nasıl** çözüldüğünü kaydetmedi. Ölçümde bu, altıncı sorunun iki biçimde de
yanıtsız kalması demekti.

Bu ders o çözümün kendisine bakar. Araç iki tarafı birleştiremediğinde dosyaya ne yazar,
yazdığı işaretler nasıl okunur, verilen çözümün doğru olduğu nasıl doğrulanır — ve iş
bittiğinde tarihçeye tam olarak neyin yazıldığı, neyin yazılmadığı.

## Aracın Karar Veremediği Yer

Üçlü birleştirme üç sürüm okur: ortak atadaki hâl, ana daldaki hâl, gelen daldaki hâl. Bir
satırı yalnız bir taraf değiştirmişse karar kendiliğinden verilir — değişen taraf alınır.
Çakışma, **iki tarafın da aynı satırı ata sürümünden ayrı biçimde değiştirdiği** yerde
doğar. Araç burada bir tercih üretmez; iki değişiklik de kasıtlıdır ve hangisinin doğru
olduğu ancak işin anlamı bilinerek söylenebilir.

Çakışmalar yalnız satır içeriğinden doğmaz. Bir taraf dosyayı silmişken öbür taraf onu
değiştirmişse, bir taraf yeniden adlandırmışken öbürü aynı yola yazmışsa, ya da iki taraf
aynı yolda ayrı içerikle yeni birer dosya oluşturmuşsa da karar verilemez. Bu durumların
ortak yanı şudur: ata sürümüyle karşılaştırma iki taraf için de bir değişiklik gösterir ve
ikisi bir arada uygulanamaz.

Çakışma bir hata değildir. Aracın "burada karar bende değil" demesidir; birleştirme
durdurulur, çalışma alanı yarım bırakılır ve karar insana devredilir.

## Çakışma İşaretleri

Araç kararı devrederken dosyayı boş bırakmaz: iki tarafın da içeriğini dosyaya yazar ve
aralarına ayraç koyar. Bunlara **çakışma işareti (conflict marker)** denir.

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

$ git merge rapor
Auto-merging ayar.py
CONFLICT (content): Merge conflict in ayar.py
Automatic merge failed; fix conflicts and then commit the result.

$ cat ayar.py
<<<<<<< HEAD
ESIK = 40
||||||| ortak ata
ESIK = 25
=======
ESIK = 25
BIRIM = "mm"
>>>>>>> rapor
```

`<<<<<<<` ile `|||||||` arası **bulunduğunuz taraftır**: birleştirmeyi başlattığınız dal,
yani `HEAD`. `|||||||` ile `=======` arası **ortak atadaki** hâldir. `=======` ile
`>>>>>>>` arası **gelen taraftır**. Üç bölümlü bu gösterim varsayılan değildir; iki
bölümlü gösterimde ata sürümü yazılmaz ve yalnız iki taraf görünür. Ata bölümü ölçüyü
verir: yukarıdaki dökümde ata `ESIK = 25` diyor, yani eşik değerini **değiştiren taraf
`HEAD`**, satırı olduğu gibi bırakıp altına yeni bir satır ekleyen taraf `rapor`. Bu
bilgi olmadan iki taraf da eşit görünür ve seçim körleme yapılır.

İşaretler dosyanın kendisine yazılır, dosya çalışma alanında kalır ve o hâliyle
derlenemez. Aracın kendi kaydında ise aynı çakışma üç ayrı **aşama** olarak durur: ata,
bulunduğunuz taraf ve gelen taraf. Dosyayı elle düzenlemeden önce üç sürümü ayrı ayrı
görmek bu aşamalardan yapılır.

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

$ git status --short
UU ayar.py
M  olcum.py

$ git diff --base ayar.py
$ git diff --ours ayar.py
$ git diff --theirs ayar.py
```

`UU` iki tarafın da aynı yolu değiştirdiğini gösterir; silme ve yeniden adlandırma
çakışmaları başka harf çiftleriyle işaretlenir. Üç `diff` çağrısı çalışma alanındaki
dosyayı sırasıyla ata, bulunulan taraf ve gelen tarafla karşılaştırır.

## Çözümün Verilmesi ve Doğrulanması

Çözmek, dosyayı istenen son hâline getirmek ve işaretleri silmektir. Sonuç iki taraftan
birinin aynısı olabileceği gibi ikisinden de farklı, elle yazılmış bir üçüncü içerik de
olabilir — kurgudaki gibi hem yeni eşiğin hem yeni birimin durduğu bir hâl. Dosya
hazırlandıktan sonra hazırlık alanına eklenmesi, aracın gözünde "bu yol çözüldü"
demektir; bütün yollar çözüldüğünde birleştirme işlemesi yazılır.

Araç bir kısayol da sunar: çakışan yolu tamamen bir tarafın sürümüyle doldurmak. Bu
kısayol makine tarafından üretilen dosyalarda yerindedir, çünkü orada iki taraftan biri
yeniden üretilebilir. Elle yazılmış bir dosyada ise kısayol, öbür tarafın o dosyadaki
bütün değişikliklerini sessizce atar; atılan değişiklik dosyada görünmez olur ve
sınamalar o tarafı kapsamıyorsa hiçbir yerde belirti vermez.

Doğrulamanın üç ayrı katmanı vardır ve üçü de gereklidir.

**Birincisi mekanik:** dosyada işaret kalmadığından emin olmak. Kalan bir `<<<<<<<`
satırı çoğu dilde sözdizimi hatası verir, ama biçimlendirilmiş metin ya da veri
dosyalarında sessizce durabilir. Ağaçta işaret dizisi araması bunu yakalar.

**İkincisi bütünlük:** çözülmüş dosyanın iki tarafın da amacını taşıdığını görmek.
Çakışmanın dar bakılan tehlikesi budur — birleştirmeyi yapan kişi genellikle iki taraftan
yalnız birini yazmıştır ve öbürünün ne yapmak istediğini bilmez. Bu yüzden seçim, iki
tarafın kodunu birleştirmekten çok iki niyeti uzlaştırmaktır.

**Üçüncüsü davranışsal:** sınamaların çalıştırılması. Çözülmüş dosya derlenebilir olabilir
ve yine de yanlış olabilir: iki taraf ayrı ayrı doğruyken birleşiği yanlış olan bir hâl
gayet olağandır. Çakışma çözümü, sınamaların en gerekli olduğu yerdir.

Çözümden geri dönmenin güvenli yolu birleştirmeyi **iptal etmektir**; araç bunun için ayrı
bir seçenek taşır ve çalışma alanını birleştirme öncesindeki hâline döndürür. Yarım kalmış
bir birleştirmeyi elle temizlemeye çalışmak yerine iptal edip baştan başlamak her zaman
ucuzdur.

Aracın çözümü hatırlayan bir yeteneği de vardır: aynı çakışma daha sonra yeniden
karşınıza çıktığında önceki çözümü kendiliğinden uygular. Bu yetenek, uzun ömürlü bir
dalın aynı çakışmayı defalarca doğurduğu durumda emek kazandırır. Ölçüm açısından önemli
olan yanı şudur: kaydettiği çözüm **deponun yerel bir dizininde** durur, tarihçeye
yazılmaz ve kimseyle paylaşılmaz. Çözüm bilgisinin tarihçenin dışında yaşadığı ilk yer
budur.

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

- **BR8** — Çakışma, üçüncü adımda `olcum` ile `rapor` dallarının aynı dosyaya
  dokunmasından doğar. Kurgu bunu bilir; tarihçenin bilmesi gerekmez.
- **BR9** — Ölçüm dört tümleştirme biçimini de kurar. Biçimlerin tanımı ortak kurgudaki
  tanımdır ve bu derste değiştirilmez.
- **BR10** — Altıncı soru, tarihçede seçilen tarafı taşıyan bir alan aranarak ölçülür.
  Alanın adı değil, **varlığı** ölçülür.
- **BR11** — Çözüm kaydı üç alandan oluşur: seçilen taraf, gerekçe ve kararı veren rol.
  Üçü de aracın kendiliğinden yazdığı bir alan değildir.
- **BR12** — Sıkıştırmada bir işlemenin dosya alanı tek ad değil, ad listesidir: ortak
  dosyaya dokunulduğu okunur, dokunan işleme ayrı ayrı okunamaz.
- **BR13** — Gerekçenin işleme mesajına yazılması ölçümde **tek bir değişikliktir**:
  birleştirme işlemesine üç alan eklenir, başka hiçbir şey değişmez.
- **BR14** — Kümenin çözünürlüğü on iki işlemede **1/12**, altı soruda **1/6**.

## Ölçüm

```python
"""Cakismanin cozumu tarihceye ne yaziyor.

Bolum 1 - cakismayi doguran iki isleme dort bicimde nerede duruyor.
Bolum 2 - altinci soru dort bicimde de aranir.
Bolum 3 - tek degisiklik: cozumun gerekcesi isleme mesajina yazilir.
"""
TOHUM = 20260813
DALLAR = ("olcum", "rapor", "kimlik")
DOSYALAR = {"olcum": "olcum.py", "rapor": "rapor.py", "kimlik": "kimlik.py"}
KUSURLU = ("rapor", 2)
ORTAK_DOSYA = "ayar.py"
COZUM_ALANLARI = ("secilen", "gerekce", "karar_veren")


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 tumlestir(kayit, bicim):
    t = []
    if bicim == "birlestirme islemesi":
        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})
            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})
    elif bicim == "yeniden temellendirme":
        for dal in DALLAR:
            for k in [x for x in kayit if x["dal"] == dal]:
                t.append({**k, "dal_kaydi": None, "zaman_korundu": False})
    elif bicim == "sikistirma":
        for dal in DALLAR:
            grup = [x for x in kayit if x["dal"] == dal]
            t.append({"dal": dal, "sira": 0,
                      "dosya": sorted({x["dosya"] for x in grup}),
                      "kusurlu": any(x["kusurlu"] for x in grup),
                      "zaman": max(x["zaman"] for x in grup), "dal_kaydi": dal,
                      "zaman_korundu": False, "sikisik": len(grup)})
    elif bicim == "ileri sarma":
        for k in sorted(kayit, key=lambda x: x["zaman"]):
            t.append({**k, "dal_kaydi": None, "zaman_korundu": True})
    return t


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


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


def dokunan(t, ad):
    """Tarihceden ad dosyasina dokundugu okunabilen isleme sayisi."""
    return sum(1 for x in t if x["dosya"] == ad
               or (isinstance(x["dosya"], list) and ad in x["dosya"]))


def ayri_okunabilir(t, ad):
    """Yalniz o dosyaya dokunan tek bir isleme olarak okunabilenler."""
    return sum(1 for x in t if x["dosya"] == ad)


def mesaja_yaz(t):
    """Tek degisiklik: cozumun gerekcesi bir isleme mesajina yazilir."""
    y = [dict(x) for x in t]
    for x in y:
        if x.get("birlesme") and x["dal"] == "rapor":
            x.update({"secilen": "olcum tarafi", "gerekce": "esik alani",
                      "karar_veren": "birlestiren"})
    return y


BICIMLER = ("birlestirme islemesi", "yeniden temellendirme", "sikistirma",
            "ileri sarma")
kayit = gelisim()
T = {b: tumlestir(kayit, b) for b in BICIMLER}
catisan = [(k["dal"], k["sira"]) for k in kayit if k["dosya"] == ORTAK_DOSYA]

print(f"gerçek gelişim: {len(kayit)} işleme | {ORTAK_DOSYA} dosyasına dokunan "
      f"{len(catisan)} işleme: {catisan}")
print()
print(f"{'biçim':<24s} {'işleme':>6s} {'dokunan':>7s} {'ayrı':>5s}"
      f" {'dosya izi':>9s} {'çakışma kararı':>14s}")
for b in BICIMLER:
    print(f"{b:<24s} {len(T[b]):6d} {dokunan(T[b], ORTAK_DOSYA):7d}"
          f" {ayri_okunabilir(T[b], ORTAK_DOSYA):5d}"
          f" {('evet' if s4_dosya(T[b]) else 'hayır'):>9s}"
          f" {('evet' if s6_cakisma(T[b]) else 'hayır'):>14s}")
print(f"altıncı soruyu yanıtlayan biçim: "
      f"{sum(s6_cakisma(T[b]) for b in BICIMLER)}/{len(BICIMLER)}")
print()
M = mesaja_yaz(T["birlestirme islemesi"])
print(f"{'tarihçe':<34s} {'çözüm alanı taşıyan':>19s} {'çakışma kararı':>14s}")
for ad, t in (("araç ne yazdıysa", T["birlestirme islemesi"]),
              ("gerekçe işleme mesajına yazılınca", M)):
    tasiyan = sum(1 for x in t if any(a in x for a in COZUM_ALANLARI))
    print(f"{ad:<34s} {f'{tasiyan}/{len(t)}':>19s}"
          f" {('evet' if s6_cakisma(t) else 'hayır'):>14s}")
```

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

biçim                    işleme dokunan  ayrı dosya izi çakışma kararı
birlestirme islemesi         15       2     2      evet          hayır
yeniden temellendirme        12       2     2      evet          hayır
sikistirma                    3       2     0     hayır          hayır
ileri sarma                  12       2     2      evet          hayır
altıncı soruyu yanıtlayan biçim: 0/4

tarihçe                            çözüm alanı taşıyan çakışma kararı
araç ne yazdıysa                                  0/15          hayır
gerekçe işleme mesajına yazılınca                 1/15           evet
```

## Dördü de Yanıtlayamaz

Üst tablonun son sütunu bu kursun üçüncü iddiasını ödüyor: **çakışma kararı dört biçimde
de hayır.** Yanıtlayan biçim sayısı **0/4**. Bu, biçimlerden birinin öbürlerinden kötü
olduğu anlamına gelmez; ölçülen dört biçimin hiçbirinde böyle bir alanın **bulunmadığı**
anlamına gelir.

Tarihçenin ne kaydettiğine bakıldığında ayrım netleşir. Ortak dosyaya dokunan iki işleme
üç biçimde de **2** olarak okunuyor: çakışmanın hangi dosyada doğduğu ve hangi iki işin
oraya dokunduğu bulunabiliyor. Sıkıştırmada dosya adı ayrı bir işlemede değil, bir işleme
grubunun dosya listesi içinde duruyor; dokunulduğu görülüyor ama ayrı okunabilen işleme
sayısı **0** ve dosya izi sorusu bu biçimde **hayır** veriyor.

Yani tarihçe çakışmanın **olduğunu** kaydediyor — çakışmanın doğduğu yer üç biçimde
bulunabiliyor. Kaydetmediği şey çözümün kendisidir: hangi tarafın seçildiği, hangi
satırların elle yazıldığı, kararı kimin verdiği ve neden verdiği. Bu dört bilginin
hiçbiri araç tarafından yazılan bir alanda durmuyor.

Bunun bir araç eksikliği olmadığını görmek için kaydın ne olduğunu düşünmek yeterli. Bir
işleme, ağacın bir hâlini ve öncüllerini taşır. Birleştirme işlemesinin taşıdığı ağaç,
çözülmüş dosyayı zaten içerir — sonuç kayıtlıdır. Kayıtlı olmayan şey **süreçtir**: iki
adaydan hangisinin neden seçildiği, sonucun kendisinden okunamaz. Araç yalnız sonucu
saklar, çünkü sakladığı şey ağaçtır.

## Gerekçenin Tek Yeri

Alt tablo bir sonraki adımı ölçüyor. Ölçümde değiştirilen tek şey şu: çözümün gerekçesi
birleştirme işlemesinin mesajına yazılıyor. Üç alan — seçilen taraf, gerekçe, kararı veren
rol — o tek işlemeye ekleniyor.

Sonuç, on beş işlemelik tarihçenin **1**'inde çözüm kaydı bulunması ve altıncı sorunun
**evet** vermesidir. Oran **1/15**: kümenin çözünürlüğünün üzerinde, ama tarihçenin
tamamına göre küçük bir yer. Bu küçüklük tesadüf değildir; çözüm kaydı ancak çakışmanın
kapatıldığı işlemede anlamlıdır.

Buradan kursun en pratik sonucu çıkar: **çakışma çözümünün gerekçesi işleme mesajına
yazılmazsa hiçbir yerde yoktur.** Araç onu yazmaz, dosya onu taşımaz, sınamalar onu
anlatmaz. Çözümü hatırlayan yerel yetenek bile onu yalnız o depoda tutar ve kimseyle
paylaşmaz. Aylar sonra "bu satır neden böyle" diye soran kişinin bakabileceği tek yer
mesajdır ve mesaj boşsa yanıt kimsede değildir.

Bunun somut karşılığı şudur: birleştirme işlemesinin varsayılan mesajı yalnız hangi dalın
birleştirildiğini yazar ve boş bırakılırsa öyle kalır. Çakışmalı bir birleştirmede o
mesajın üç şeyi taşıması gerekir — hangi dosyada çakışıldığı, hangi tarafın hangi
gerekçeyle seçildiği ve elle yazılmış bir içerik varsa onun ne olduğu. Üçü de üç satırdır
ve üçü de yazılmadığında geri getirilemez.

## Özet

- Çakışma, iki tarafın da aynı satırı ata sürümünden ayrı biçimde değiştirdiği yerde
  doğar; araç tercih üretmez, kararı devreder ve birleştirmeyi yarıda bırakır.
- Çakışma işaretleri bulunulan tarafı, ata sürümünü ve gelen tarafı dosyaya yazar; ata
  bölümü hangi tarafın gerçekten değişiklik yaptığını gösterir ve seçimi körlemeden
  çıkarır.
- Çözüm üç katmanda doğrulanır: işaret kalmadığı, iki tarafın amacının korunduğu ve
  sınamaların geçtiği. Geri dönmenin güvenli yolu birleştirmeyi iptal etmektir.
- Ortak dosyaya dokunan **2** işleme üç biçimde ayrı ayrı okunur, sıkıştırmada **0**;
  ama çakışma kararı sorusunu dört biçimin dördü de yanıtlayamaz — **0/4**.
- Gerekçe işleme mesajına yazıldığında on beş işlemenin **1**'i çözüm kaydını taşır ve
  altıncı soru yanıtlanır; yazılmadığında çözümün gerekçesi hiçbir yerde durmaz.

## Sonraki Adım

Bu derste çakışma tek bir yerde, birleştirme işlemesinin yazıldığı anda çözüldü. Çözüm bir
kez verildi ve bir kez kaydedildi. Tarihçeyi çatallanmasız, tek çizgi hâlinde tutmak
isteyen bir biçim ise dalın işlemelerini ana dalın ucuna **yeniden yazar** — ve o zaman
aynı çakışma her işleme için ayrı ayrı sorulabilir. Sonraki ders bu biçime bakar: on iki
işleme on iki olarak kalır ama hangi üç soru yanıtlanır, hangi bilgi silinir, ve
paylaşılan bir dalda uygulandığında neden geri alınamaz.
