---
title: 'Zorlayıcı İtme Disiplini'
source: 'https://academia.sh/tr/kurslar/ileri-git/zorlayici-itme-disiplini'
course: 'İleri Git'
language: tr
updated: '2026-08-17T18:10:43+00:00'
license: 'CC BY-SA 4.0'
---

# Zorlayıcı İtme Disiplini

Bin işlemelik bir tarihçede son işlemeyi değiştirmek 1, ilk işlemeyi değiştirmek 1000 kimlik değiştirir; ama iki durumda da yedi kopyanın yedisi yeniden eşitlemek zorundadır ve dayanaksız kalan yerel iş aynı kalır — bedel değişikliğin büyüklüğüyle değil kopya sayısıyla ölçeklenir.

Önceki derste bedel bir kez sayıldı ve tek bir depoda kaldı: bin kimlik, beş bin altı yüz
kırk nesne, sıfır ortak ata. Sayı, işlemin yerel yarısını anlatıyordu. Yeniden yazılmış bir
tarihçenin bir işe yaraması için karşı tarafa da yazılması gerekir — ve karşı taraf onu
olağan yolla kabul etmez.

Bu ders o reddin neden konduğunu, nasıl aşıldığını ve aşıldığında kimin ne kaybettiğini ele
alır. Bir yordam dersi değildir: aşağıda hiçbir zorlayıcı itme satırı çalıştırılabilir
biçimde yazılmaz. Ölçülen şey aracın nasıl çağrıldığı değil, çağrının **kimin üstünde**
bıraktığı bedeldir.

## Reddin Nedeni

Getirme, çekme ve itme arasındaki ayrım önceki kursta kuruldu ve burada tekrarlanmaz. Bir
tanesi burada gerekli: itme, karşı taraftaki bir başvurunun gösterdiği yeri değiştirmeyi
ister. Karşı taraf bu isteği yalnız bir koşulda kabul eder — istenen yeni uç, o anki ucu
**içeriyorsa**. İçeriyorsa hiçbir şey kaybolmaz; karşı taraftaki her işleme yeni uçtan geriye
doğru yürünerek bulunabilir.

Yeniden yazma tam olarak bu koşulu bozar. Yeni zincir eski zincirin işlemelerini içermez,
onların yerine başka kimlikli işlemeler koyar. Karşı taraf isteği reddeder ve gerekçesini
söyler.

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

$ git push kaynak olcum
 ! [rejected]        olcum -> olcum (non-fast-forward)
error: failed to push some refs to 'kaynak'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart.
```

Ret iletisi bir kusuru değil, bir kuralın işlediğini bildiriyor. Bu ret deponun tek yerleşik
korumasıdır. Karşı taraftaki başvurunun
gösterdiği zinciri **yalnız büyüterek** değiştirmeye izin verir; küçültmeye ya da başka bir
zincirle değiştirmeye izin vermez.

## Reddi Aşmak

Aracın bu reddi devre dışı bırakan bir seçeneği vardır ve adı **zorlayıcı itmedir**.
Yaptığı iş tek cümleyle söylenebilir: karşı taraftaki başvuruyu, eski değerini hiç
sormadan yeni zincirin ucuna taşır. Eski zincir silinmez; onu gösteren başvuru kalmadığı
için erişilemez kalır ve karşı tarafın çöp toplama düzeni onu bir süre sonra temizler.

Bu satır burada tam biçimde yazılmaz. Nedeni, satırın kopyalanabilir olmasının kendisidir:
paylaşılan bir dalda çalıştırıldığında başkalarının işini o dalın kaydından siler ve
**işlem geri alınamaz** — geri alınabilirliği yalnız başkalarının elindeki kopyalar sağlar,
ki bunun ne demek olduğu dersin sonunda ayrıca yazılır.

Aynı ailenin ikinci bir seçeneği, karşı taraftaki başvurunun **beklenen değerini** de
isteğe ekler: uç beklenen yerdeyse yazar, değilse reddeder. Bu seçenek zorlayıcı itmeyi
güvenli hâle getirmez; yalnız **görmediğiniz** bir işi ezmenizi engeller. Gördüğünüz ve
yine de ezdiğiniz iş için hiçbir koruma yoktur.

## Bedeli Kim Öder

Yeniden yazmanın bedeli iki ayrı kalemde durur. Birincisi yazanın kalemidir: yeniden
yazılan zincirin nesneleri bir kez üretilir. İkincisi kopyaların kalemidir: aynı zinciri
her kopya yeniden almak zorundadır. Ölçüm ikisini yan yana koyar ve değiştirilen işlemenin
yerini dört kez değiştirir.

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

- **YZ17** — Kurgu önceki derslerin kurgusudur ve değiştirilmez; ölçüm **1000** işlemelik
  tarihçe üzerinde yapılır.
- **YZ18** — Depo **yedi** kopyada yaşıyor. Kopya sayısı ölçümün girdisidir ve yeniden
  yazmayı yapan kişinin seçimi değildir.
- **YZ19** — Dal ucunun kimliği değiştiği anda her kopya yeniden eşitlemek zorundadır.
  Ölçüm eşitlemek **zorunda olan** kopyayı sayar; eşitleyip eşitlemedikleri ölçümün dışıdır.
- **YZ20** — Yazanın bedeli yeniden yazdığı zincirin nesne sayısıdır; kopyaların bedeli aynı
  sayının kopya adedi kadar katıdır. Birim **dokunulan nesnedir**.
- **YZ21** — Her kopyanın eski ucun üzerine yazdığı bir miktar yerel iş vardır (kurgudan
  gelir, sıfır ile üç işleme arası) ve bu iş henüz karşı tarafa yazılmamıştır.
- **YZ22** — Zorlayıcı itmeden sonra bu yerel işin dayanağı ortadan kalkar. Dayanaksız kalan
  iş, değiştirilen işlemenin **yerinden bağımsızdır**: uç değiştiği anda her yerel zincir
  dayanağını yitirir.
- **YZ23** — Kimlik ve kopya sayıları bir bedel değil, kümenin genişliğidir; bedel yalnız
  nesne sütununda okunur.
- **YZ24** — Çözünürlük işlemede **1/1000**, kopyada **1/7**'dir.

## Ölçüm

```python
"""Zorlayici itme: yeniden yazmanin bedelini yazan odemez.

Bolum 1 - dort konum: kimligi degisen, yazanin ve kopyalarin dokundugu nesne.
Bolum 2 - kopyalarin eski ucun uzerine yazdigi yerel is.
Bolum 3 - paylasim durumu: tek guvenli kosul hangisi.
"""
TOHUM = 20260814
DOSYALAR = ("olcum.py", "rapor.py", "kimlik.py", "ayar.py", "belge.md")
KOPYA = 7


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

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


def tarihce(n, tohum=TOHUM):
    """n islemelik dogrusal tarihce; her isleme bir dosyaya dokunuyor."""
    r, liste = uretec(tohum), []
    for i in range(n):
        dosya = DOSYALAR[r(5)]
        ikili = r(11) == 0
        liste.append({"no": i + 1, "dosya": dosya, "ikili": ikili,
                      "nesne": 2 + (40 if ikili else 0)})
    return liste


def yeniden_yaz(t, konum):
    sonra = [x for x in t if x["no"] >= konum]
    return len(sonra), sum(x["nesne"] for x in sonra)


def yeniden_esitleyen(kopya_sayisi, konum, t):
    """Yeniden yazilan tarihceyi kimler yeniden esitlemek zorunda."""
    degisen, _ = yeniden_yaz(t, konum)
    return kopya_sayisi if degisen else 0


def kopyalar(sayi=KOPYA, tohum=TOHUM):
    """Her kopyanin eski ucun uzerine yazdigi yerel isleme sayisi."""
    r = uretec(tohum)
    return [{"no": i + 1, "yerel": r(4)} for i in range(sayi)]


T = tarihce(1000)
K = kopyalar()

print(f"{'değiştirilen yer':>17s} {'kimliği değişen':>16s}"
      f" {'yazanın nesnesi':>16s} {'eşitleyen kopya':>16s}"
      f" {'kopyaların nesnesi':>19s}")
for konum in (1000, 900, 500, 1):
    isl, nes = yeniden_yaz(T, konum)
    k = yeniden_esitleyen(KOPYA, konum, T)
    print(f"{konum:17d} {isl:16d} {nes:16d} {k:16d} {k * nes:19d}")

print()
print("kopyaların eski uç üzerine yazdığı yerel işleme:",
      [x["yerel"] for x in K], "toplam", sum(x["yerel"] for x in K))
print()
print(f"{'paylaşım durumu':<16s} {'kopya':>6s} {'eşitleyen':>10s}"
      f" {'dayanaksız (son işleme)':>24s} {'dayanaksız (ilk işleme)':>24s}")
for ad, sayi in (("paylaşılmamış", 0), ("üç kopya", 3), ("yedi kopya", 7)):
    dayanaksiz = sum(x["yerel"] for x in K[:sayi])
    print(f"{ad:<16s} {sayi:6d} {yeniden_esitleyen(sayi, 1000, T):10d}"
          f" {dayanaksiz:24d} {dayanaksiz:24d}")
```

```
 değiştirilen yer  kimliği değişen  yazanın nesnesi  eşitleyen kopya  kopyaların nesnesi
             1000                1                2                7                  14
              900              101              602                7                4214
              500              501             3002                7               21014
                1             1000             5640                7               39480

kopyaların eski uç üzerine yazdığı yerel işleme: [0, 0, 3, 2, 2, 2, 0] toplam 9

paylaşım durumu   kopya  eşitleyen  dayanaksız (son işleme)  dayanaksız (ilk işleme)
paylaşılmamış         0          0                        0                        0
üç kopya              3          3                        3                        3
yedi kopya            7          7                        9                        9
```

## Bin Kat Fark, Sıfır Kat Fark

Üst tablonun sol yarısı beklenen şeyi veriyor. Son işlemeyi değiştirmek **1** kimlik
değiştiriyor ve yazana **2** nesneye mal oluyor; ilk işlemeyi değiştirmek **1000** kimlik
değiştiriyor ve **5640** nesne demek. Aradaki fark bin kat. Bir yazım hatasını düzeltmekle
deponun tamamını dönüştürmek arasında, yazanın gördüğü bedel bakımından, uçurum var.

Sağ yarı bu uçurumu görmüyor. **Eşitlemek zorunda olan kopya sayısı dört satırda da 7.**
Yedi kopyanın yedisi, ne kadar küçük bir değişiklik olursa olsun, dal ucunun yeni kimliğini
almak ve kendi durumunu ona göre düzeltmek zorunda. Fark bin kat değil, **sıfır kat**. Yazanın gördüğü uçurum, kopyaların gördüğü tabloda hiç
yoktur.

Kopyaların nesne sütunu bunun mutlak karşılığını veriyor: son işlemeyi değiştirmenin
karşılığı **14** nesne, ilk işlemeyi değiştirmenin karşılığı **39480**. İki sayı da yazanın
sütunundakinin **yedi katı** — ve yedi, yazanın belirlediği bir sayı değil. Kursun üçüncü
iddiası buradadır: **bedel değişikliğin büyüklüğüyle değil, kopya sayısıyla ölçeklenir ve o
sayı yeniden yazmayı yapanın elinde değildir.** Yeniden yazan kişi kendi kaleminde en ucuz
satırı seçebilir; kopyaların kalemi seçime bağlı değildir.

Alt tablo bunu en sert biçimde söylüyor. Kopyaların eski uç üzerine yazdığı yerel iş toplam
**9** işleme — yedi kopyanın üçünün elinde hiç yerel iş yok, dördünün elinde var. Zorlayıcı
itmeden sonra dayanaksız kalan iş **9** ve bu sayı iki sütunda da aynı: **son** işlemeyi
değiştirseniz de **ilk** işlemeyi değiştirseniz de dokuz işleme dayanağını yitiriyor. Uç
değişti mi değişmedi mi — sorunun tamamı bu; ne kadar değiştiği kimseyi ilgilendirmiyor.

Tabloda tek bir güvenli satır var: **paylaşılmamış**. Kopya sayısı sıfır olduğunda eşitleyen
sıfır, dayanaksız kalan sıfır. Ölçümün ürettiği ölçüt budur ve tek ölçüt budur.

Ara satırlar bir ayrıntıyı da gösteriyor. Dokuz yüzüncü işlemeden yeniden yazmak **101**
kimlik değiştiriyor ama **602** nesneye dokunuyor; iki yüz iki değil. Fark, o aralığa düşen
ikili varlıklardan geliyor — kimlik saymakla nesne saymak aynı sonucu vermiyor ve bu dersin
birimi nesne. Kopyaların sütunu da bu yüzden kimlik sayısını değil nesne sayısını yediyle
çarpıyor.

## Kopya Ne Yapmak Zorunda

"Yeniden eşitlemek" tek bir işlem değil, bir karardır ve kararı kopyanın sahibi verir. İki
yol vardır ve ikisi de bedelsiz değildir.

**Birinci yol**, yerel dalı yeni uca sıfırlamaktır. Yerel iş varsa bu yol onu bırakır;
işlemeler erişilemez kalır ve ancak o kopyanın kendi referans günlüğünden bulunur. Yerel iş
yoksa yol temizdir ve ölçümdeki üç kopya için durum budur.

**İkinci yol**, yerel işi yeni zincirin üstüne yeniden temellendirmektir. Hiçbir şey
kaybolmaz, ama yerel işlemeler de yeni kimlik alır ve bu kursun ilk dersindeki bedel bu kez
kopyanın kaleminde yazılır. Dört kopya için ödenen budur: dokuz işlemenin dokuzu yeniden
yazılır.

Üçüncü bir yol, en azından bedelsiz bir üçüncü yol, yoktur. Yerel işi olduğu gibi karşı tarafa yazmayı denemek, aynı reddi bu kez
kopyanın karşısına çıkarır — ve o noktada kopyanın sahibi de zorlayıcı itme düğmesine
bakıyor olur. Bir zorlayıcı itmenin ikincisini davet etmesi, dersin başlığındaki disiplinin
neden bir kişinin değil ekibin disiplini olduğunu gösterir.

## Kimin Haberi Olmadan

İşlemin en can sıkıcı yanı sayılarda görünmez. Zorlayıcı itme **tarihçeye yazılmaz.** Yeni
tarihçede, birinin bir şeyi ezdiğini söyleyen hiçbir işleme, hiçbir alan yoktur. Önceki
kursun altıncı sorusu çakışma kararının kayda geçmediğini gösteriyordu; burada kayda
geçmeyen şey, kaydın kendisinin değiştirilmiş olmasıdır.

Kopyalar da anında öğrenmez. Bir kopya karşı tarafa bakmadığı sürece elindeki eski zinciri
geçerli sanmaya devam eder, üstüne işleme yazar ve dayanaksız işini büyütür. Öğrenme anı bir
sonraki getirmedir. O ana kadar geçen sürede yapılan her yeni işleme, ezilmiş bir uca eklenen
bir işlemedir.

Öğrenme anının kendisi de yanıltıcı olabilir. Getirmenin ardından çekme çağrılırsa araç iki
zinciri birleştirmeyi dener ve genellikle başarır: eski zincir ile yeni zincir aynı
değişiklikleri taşıdığı için birleşme sessizce tamamlanır. Sonuç, aynı değişikliklerin iki
ayrı kimlikle iki kez bulunduğu bir tarihçedir. Bunu fark etmenin tek yolu tarihçeye
bakmaktır; hiçbir uyarı çıkmaz. Ezilen dalın yeniden ezilmesi de çoğu kez böyle başlar —
kopyalardan biri eski zinciri geri getirir, yeniden yazan kişi bunu görür ve işlemi
tekrarlar.

Bu üç gerçek birlikte, işlemi bir araç sorunu olmaktan çıkarıp bir **bildirim sorunu**
hâline getirir. Araç kimseyi uyarmaz, tarihçe kimseye söylemez; söyleyecek olan yeniden
yazmayı yapan kişidir. Duyurunun içeriği de bellidir: hangi dal, hangi an, ve kopyaların
hangi yolu izlemesi bekleniyor.

## Disiplin

Ölçütler ölçümden çıkar ve dördü de kısa yazılabilir.

**Birincisi:** zorlayıcı itme yalnız **paylaşılmamış** dallarda uygulanır. Bir dalın
paylaşılmamış olması, "kimse ondan çalışmıyor" varsayımı değil, kontrol edilebilir bir
durumdur.

**İkincisi:** ana dal, yayım dalı ve etiketlerin gösterdiği zincirler yeniden yazılmaz.
Bir değişikliği geri almak gerektiğinde yol yeniden yazmak değil, tersini yapan yeni bir
işleme yazmaktır — bu yol Sürüm Kontrolüne Giriş kursunda devirme adıyla kuruldu ve
tarihçeyi hiç değiştirmediği için hiçbir kopyayı ilgilendirmez.

**Üçüncüsü:** paylaşılan bir inceleme dalının yeniden yazılması gerekiyorsa işlem önceden
duyurulur, sonrasında da duyurulur. Beklenen değeri isteğe ekleyen seçenek kullanılır;
o seçenek görülmemiş işi korur, görülmüş işi korumaz.

**Dördüncüsü:** koruma araca değil, karşı tarafa konur. Depo sunucusunda dal koruma
yetenekleri bulunur ve ileri sarma dışındaki güncellemeleri reddedecek biçimde
ayarlanabilir. Bir kuralın araç tarafında değil sunucu tarafında durması, onu unutulabilir
olmaktan çıkarır.

Dört ölçütün pratikte hangi noktada çöktüğü de söylenmelidir. Çoğu zaman kural bilinir ve
uygulanır; kaza, bir dalın **paylaşılmamış sanılmasından** doğar. Bir dalın adı kişiseldir,
kimsenin ondan çalışmadığı varsayılır, oysa biri onu bir inceleme sırasında getirmiştir.
Varsayımı sınamanın yolu karşı tarafa bakmaktır, kendi belleğine değil; dalın karşı taraftaki
durumu getirilirse varsayım bir ölçüme dönüşür.

Her kayıp yolunun bir kurtarma yolu vardır ve burada üçü sayılabilir. Karşı taraftaki eski
zincir başvurusuz kaldığında kurtarma **kopyalardadır**: eski ucu hâlâ gösteren bir kopya
onu yeni bir dal olarak geri yazabilir; ezilen tarafın yedeği, bedeli ödeyen taraftır. Bir
kopyanın dayanaksız kalan yerel işi, o kopyanın kendi referans günlüğünden bulunup yeni
zincirin üstüne taşınabilir. Yeniden yazmayı yapan kişinin kaybettiği eski uç, yedek dal ya
da yerel referans günlüğünden okunur. Üç yolun ikisi aynı düzeneğe dayanıyor ve o düzeneğin
bir ömrü var.

## Özet

- Olağan itme yalnız karşı taraftaki ucu **içeren** bir zinciri kabul eder; yeniden yazma bu
  koşulu bozduğu için reddedilir ve ret deponun tek yerleşik korumasıdır.
- Zorlayıcı itme reddi kaldırır: başvuruyu eski değerini sormadan taşır. Satır burada tam
  biçimde yazılmaz; paylaşılan bir dalda geri alınamaz.
- Bin işlemelik tarihçede son işlemeyi değiştirmek **1** kimlik ve **2** nesne, ilk işlemeyi
  değiştirmek **1000** kimlik ve **5640** nesne demektir — ama **yedi kopyanın yedisi** dört
  durumda da yeniden eşitlemek zorundadır.
- Kopyaların ödediği **14** ile **39480** nesne arasında değişir ve her zaman yazanın
  ödediğinin **yedi katıdır**; dayanaksız kalan **9** işleme ise değiştirilen yerden
  bağımsızdır. **Bedeli yazan ödemez.**
- Ölçümün verdiği tek güvenli satır **paylaşılmamış** dallardır: sıfır kopya, sıfır
  dayanaksız iş.
- İşlem tarihçeye yazılmaz ve kopyalar bir sonraki getirmeye kadar öğrenmez; bildirim
  aracın değil, yeniden yazan kişinin işidir.

## Sonraki Adım

Bu dersin kurtarma yollarından ikisi aynı yere bakıyordu: dal ucunun eski değerini tutan
yerel kayda. O kayıt sınırsız değildir. Yeniden yazılmış bir tarihçede eski zincirin
işlemeleri erişilemez durumda durur, bir süre kurtarılabilir kalır, sonra temizlenir.
Sonraki ders o pencereyi ölçer: yeniden yazmadan sonra kaç işleme erişilebilir kalır, kaçı
yalnız kayıttan bulunabilir, ve kurtarma penceresi hangi anda kapanır.
