---
title: 'Etkileşimli Yeniden Temellendirme'
source: 'https://academia.sh/tr/kurslar/ileri-git/etkilesimli-yeniden-temellendirme'
course: 'İleri Git'
language: tr
updated: '2026-08-17T18:10:43+00:00'
license: 'CC BY-SA 4.0'
---

# Etkileşimli Yeniden Temellendirme

Bir işlemeyi değiştirmek ondan sonraki her işlemenin kimliğini değiştirir; ortadan yeniden yazmak 50, 200, 1000 ve 4000 işlemelik tarihçelerde sırasıyla 252, 362, 3002 ve 11322 nesneye dokunur ve oran her ölçekte yaklaşık yarıda kalır.

Önceki kurs tarihçeyi tek bir ölçüyle okudu: bir tümleştirme biçiminin değeri, ürettiği kod
değil, bıraktığı tarihçenin yanıtlayabildiği soru sayısıydı. Dört biçim aynı kodu üretiyor ve
altı sorunun sırasıyla beşini, üçünü, ikisini ve üçünü yanıtlıyordu. O kursta tarihçe
**verilmiş bir kayıttı**: sorular ona sorulur, yanıtlar sayılırdı. Kayıt yazıldıktan sonra
onu değiştirmek gündeme gelmiyordu.

Bu kurs aynı kaydı bir nesne olarak ele alır. Tarihçe yeniden yazılabilir: işleme mesajı
düzeltilebilir, iki işleme tek işlemeye indirilebilir, sıra değiştirilebilir, bir işleme
tümüyle atılabilir. Ölçü de bununla birlikte değişir. Orada ölçülen **yanıtlanan soruydu**;
burada ölçülen **dokunulan nesnedir**. Bu dersin sorusu şudur: bir işlemeyi geriye dönüp
değiştirmek tarihçenin ne kadarına dokunur, ve tarihçe büyüdükçe bu oran düşer mi.

## Kimlik Zincir Boyunca Yayılır

Bir işlemenin kimliği içeriğinden türetilir. Kimliğe giren alanlar bellidir: o anki dosya
ağacı, yazar, işleyen, zaman damgası, mesaj ve **öncülün kimliği**. Son alan bu kursun
tamamını belirler. Öncülün kimliği değiştiğinde ardılın kimliği de zorunlu olarak değişir,
çünkü ardılın içeriği öncülün kimliğini taşır. Kimlik içerikten üretildiği için bu
kaçınılmazdır: aynı kimliği koruyup içeriği değiştirmenin yolu yoktur, olsaydı kimlik bir
kimlik olmazdı.

Bunun sonucu tek cümlede yazılabilir: **bir işlemeyi değiştirmek, ondan sonraki her
işlemenin kimliğini değiştirir.** Tek bir yazım hatasını düzeltmekle bütün bir dosyayı
tarihçeden çıkarmak arasında bu bakımdan fark yoktur; ikisi de aynı noktadan sonrasını
yeniden üretir. Değişikliğin **büyüklüğü** bedeli belirlemez, **yeri** belirler.

Eski işlemeler bu sırada silinmez. Depoda dururlar; onları gösteren hiçbir dal ya da etiket
kalmadığı için **erişilemez** hâle gelirler. Erişilemez olmak yok olmak değildir ve bu ayrım
bu konunun dördüncü dersinin tamamıdır. Şimdilik şu kadarı yeter: yeniden yazma bir silme
değil, bir **çoğaltmadır** — eski zincir yerinde durur, yanına yeni bir zincir yazılır ve dal
ucu yeni olanı gösterir.

## Etkileşimli Kip

Yeniden temellendirme önceki kursta bir **tümleştirme biçimi** olarak kuruldu: dalın
işlemeleri yamaya çevrilir ve yeni bir taban üzerine sırayla uygulanır. O karşılaştırma
burada tekrarlanmaz. Ayrılan şey, aynı ailenin orada hiç geçmemiş olan **etkileşimli
(interactive)** kipidir.

Etkileşimli kipte araç yamaları doğrudan uygulamaz. Önce plana alınacak işlemeleri bir liste
hâlinde önünüze koyar; listedeki her satır bir işlemeyi ve o işlemeye uygulanacak eylemi
taşır. Liste kaydedilip kapatıldığında araç satırları **yukarıdan aşağıya** yürütür.

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

$ git rebase -i HEAD~3
pick 9c4d7e1 olcum: eşik değerini yazdır
pick 4a5b6c7 rapor: alan genişliğini düzelt
pick 5b6c7d8 rapor: özet satırını ekle

# r, reword = işlemeyi al, mesajını düzelt
# s, squash = işlemeyi öncülüyle birleştir
# d, drop   = işlemeyi at
```

Dört eylem bu dersin ölçüm eksenidir. **Yeniden adlandırma** işlemeyi tutar, yalnız mesajını
değiştirir. **Sıra değiştirme** satırların yerini değiştirir; tarihçedeki sıra plandaki sıra
olur. **Sıkıştırma** bir işlemeyi öncülüyle birleştirir ve sonuçtaki işleme sayısını bir
azaltır. **Atma** işlemeyi tümüyle çıkarır ve o da sayıyı bir azaltır.

Dördü de çok farklı işler yapar: biri yalnız bir metni düzeltir, öbürü bir değişikliği
tarihçeden çıkarır. Ölçümün sorduğu şey bu farkın **bedele** yansıyıp yansımadığıdır.

Bu eylemlerden biri Sürüm Kontrolüne Giriş kursunda tek başına kurulmuştu: son işlemeyi
yerinde değiştiren yetenek, hazırlık alanının o anki durumundan yeni bir işleme üretiyor ve
eskisini erişilemez bırakıyordu. Orada da bir yeniden yazma vardı, yalnız **en sığ olanıydı**
— tarihçenin ucunda duruyordu ve ardılı yoktu. Etkileşimli kip aynı işi tarihçenin herhangi
bir yerinde yapar; ardılı olan bir işlemede yapıldığında bedel de birlikte gelir.

Plan yürütülürken bir yama uygulanamayabilir. Bu durumun mekaniği önceki kursta yeniden
temellendirme biçimiyle birlikte kuruldu ve burada tekrarlanmaz. Etkileşimli kipe özgü olan
iki nokta şudur: sıkıştırma satırında araç birleşen işlemelerin mesajlarını tek bir metinde
önünüze getirir ve düzeltmenizi bekler; ve işlem yarıda iptal edildiğinde dal ucu plana
girmeden önceki yerine döner. İptal, plan yürürken elde kalan tek bütünlüklü çıkıştır.

## Bedel Nereden Başlar

Etkileşimli kip listeye kaç işleme alacağınızı sorar. Son üç işlemeyi planlarsanız araç üç
satır gösterir ve yeniden yazma üçüncü işlemeden başlar. Tarihçenin ortasındaki bir işlemeyi
düzeltmek istiyorsanız listeye o işlemeden bu yana yazılmış **her şeyi** almak zorundasınız —
düzeltilecek satır bir tane olsa bile.

Bedel bu yüzden plandaki eylem sayısıyla değil, planın **nereden başladığıyla** ölçülür.
Ölçüm bunu iki ayrı biçimde sorar: aynı konumda dört ayrı eylem, ve aynı eylem dört ayrı
derinlikte.

Planın iki sınırı burada söylenmelidir. Birincisi, listedeki satırların altında kalan
işlemelere dokunulamaz; başlangıç noktası bir kez seçildikten sonra ondan öncesi plan
dışıdır ve daha geriye gitmek yeni bir plan demektir. İkincisi, tarihçede bir çatal kenarı
varsa doğrusal plan onu olduğu gibi taşımaz: birleştirme işlemeleri ayrıca istenmedikçe
düzleştirilir ve iki öncüllü yapı tek öncüle iner. Ölçümün kurgusu doğrusaldır, bu yüzden
ikinci sınır ölçüme girmez; ama tarihçesinde çatal bulunan bir depoda planı kurmadan önce
bilinmesi gerekir.

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

- **YZ1** — Kurgu tek bir tarihçedir ve dört ölçekte kurulur: **50, 200, 1000, 4000** işleme.
  Her işleme beş dosyadan birine dokunur; on birde biri ayrıca bir ikili varlık taşır ve o
  varlığın her sürümü tarihçede ayrı bir nesne olarak durur.
- **YZ2** — Bir işlemenin nesne bedeli ağaç ve damla için **2**'dir; ikili varlık taşıyorsa
  buna **40** eklenir. Sayım deponun nesne sayımıdır, dosya sayımı değil.
- **YZ3** — Bir işlemeyi değiştirmek ondan sonraki her işlemenin kimliğini değiştirir.
  Dokunulan küme, değiştirilen konumdan tarihçenin ucuna kadar olan kapalı aralıktır.
- **YZ4** — "Ortadan yeniden yazmak" konum olarak `n // 2` demektir; ölçek değişse de kural
  değişmez.
- **YZ5** — Etkileşimli kipin dört eylemi yalnız **sonucun uzunluğunu** ayırır: sıkıştırma ve
  atma bir işleme eksiltir, yeniden adlandırma ve sıra değiştirme eksiltmez. Dokunulan küme
  dördünde de aynıdır.
- **YZ6** — Bu dersin bedel birimi **dokunulan nesnedir**. Kimliği değişen işleme sayısı bir
  bedel değil, dokunulan kümenin genişliğidir; adım birimi bu derste kullanılmaz.
- **YZ7** — Plana alınan işleme sayısı `k` ise yeniden yazma `n - k + 1` konumundan başlar.
- **YZ8** — Kümenin çözünürlüğü dört ölçekte sırasıyla **1/50, 1/200, 1/1000, 1/4000**'dir.

## Ölçüm

```python
"""Etkilesimli yeniden temellendirme: ortadan yeniden yazmanin bedeli.

Bolum 1 - dort olcekte ortadan yeniden yazma: isleme, nesne, oran.
Bolum 2 - etkilesimli kipin dort eylemi ayni konumda.
Bolum 3 - plana alinan isleme sayisi bedeli belirler.
"""
TOHUM = 20260814
DOSYALAR = ("olcum.py", "rapor.py", "kimlik.py", "ayar.py", "belge.md")
OLCEKLER = (50, 200, 1000, 4000)
EYLEMLER = ("yeniden adlandırma", "sıra değiştirme", "sıkıştırma", "atma")


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):
    """Bir islemeyi degistirmek, ondan sonrakilerin kimligini degistirir."""
    sonra = [x for x in t if x["no"] >= konum]
    return len(sonra), sum(x["nesne"] for x in sonra)


def klon_bedeli(t):
    return sum(x["nesne"] for x in t)


def etkilesimli(t, konum, eylem):
    """Dort eylem: sonucun uzunlugu degisir, dokunulan kume degismez."""
    isl, nes = yeniden_yaz(t, konum)
    return len(t) - (1 if eylem in ("sıkıştırma", "atma") else 0), isl, nes


print(f"{'işleme':>7s} {'yeniden yazılan':>16s} {'dokunulan nesne':>16s}"
      f" {'oran':>6s} {'nesne oranı':>12s}")
for n in OLCEKLER:
    t = tarihce(n)
    isl, nes = yeniden_yaz(t, n // 2)
    print(f"{n:7d} {isl:16d} {nes:16d} {isl / n:6.3f}"
          f" {nes / klon_bedeli(t):12.3f}")

print()
T = tarihce(1000)
print(f"{'eylem':<18s} {'sonuç işleme':>13s} {'kimliği değişen':>16s}"
      f" {'dokunulan nesne':>16s}")
for e in EYLEMLER:
    kalan, isl, nes = etkilesimli(T, 500, e)
    print(f"{e:<18s} {kalan:13d} {isl:16d} {nes:16d}")

print()
print(f"{'plana alınan':>13s} {'başlanan konum':>15s} {'kimliği değişen':>16s}"
      f" {'dokunulan nesne':>16s} {'oran':>6s}")
for k in (3, 10, 50, 500):
    isl, nes = yeniden_yaz(T, len(T) - k + 1)
    print(f"{k:13d} {len(T) - k + 1:15d} {isl:16d} {nes:16d}"
          f" {isl / len(T):6.3f}")
```

```
 işleme  yeniden yazılan  dokunulan nesne   oran  nesne oranı
     50               26              252  0.520        0.663
    200              101              362  0.505        0.393
   1000              501             3002  0.501        0.532
   4000             2001            11322  0.500        0.501

eylem               sonuç işleme  kimliği değişen  dokunulan nesne
yeniden adlandırma          1000              501             3002
sıra değiştirme             1000              501             3002
sıkıştırma                   999              501             3002
atma                         999              501             3002

 plana alınan  başlanan konum  kimliği değişen  dokunulan nesne   oran
            3             998                3                6  0.003
           10             991               10               20  0.010
           50             951               50              260  0.050
          500             501              500             3000  0.500
```

## Yeniden Yazma Oransal Olarak Ucuzlamaz

Üst tablo dört ölçekte aynı işlemi yapıyor: tarihçenin ortasındaki işlemeyi değiştirmek.
Dokunulan nesne **252**'den **11322**'ye çıkıyor — kırk beş kat. Sağdaki oran sütunu ise
kıpırdamıyor: **0,520 / 0,505 / 0,501 / 0,500**. Tarihçe seksen kat büyüdüğünde ortadan
yeniden yazma hâlâ işlemelerin yaklaşık **yarısına** dokunuyor.

Bu, sezgiye ters düşen bir sonuçtur. Büyüyen bir tarihçede tek bir işlemeyi düzeltmenin
**oransal** olarak daha küçük bir iş hâline geleceği düşünülebilir; olan bunun tersidir.
Oran sabit kaldığı için mutlak bedel tarihçeyle birlikte doğrusal büyür. **Yeniden yazma
oransal olarak ucuzlamaz;** ucuzlayan tek şey, uca yakın durmaktır.

Nesne oranı sütunu ayrı bir uyarı taşıyor. İşleme oranı 0,500'e yaklaşırken nesne oranı
**0,663 / 0,393 / 0,532 / 0,501** diye zıplıyor. Küçük ölçeklerde ikili varlık taşıyan
işlemelerin nereye düştüğü sonucu belirliyor: elli işlemelik tarihçede o işlemelerin çoğu
ikinci yarıda, iki yüzlükte çoğu birinci yarıda kalmış. İşleme saymakla nesne saymak aynı
şey değildir ve bu ayrımın kendisi `buyuk-depolar` konusunun ölçüsüdür. Burada yalnız şu
kaydedilir: **oran hangi birimle sayıldığına bağlıdır** ve bu dersin birimi nesnedir.

Orta tablo ikinci soruya yanıt veriyor. Dört eylem aynı konumda uygulandığında **kimliği
değişen 501**, **dokunulan nesne 3002** — dördünde de aynı. Ayrışan tek sütun sonuçtaki
işleme sayısı: sıkıştırma ve atma **999**, öbür ikisi **1000**. Yani bir mesajdaki yazım
hatasını düzeltmek ile bir işlemeyi tarihçeden tümüyle çıkarmak **aynı bedele** sahiptir.
Araç hangi eylemi seçtiğinizi umursamaz; nereden başladığınızı umursar.

Alt tablo bunu tersinden ölçüyor. Plana **3** işleme alındığında dokunulan nesne **6**;
**10** alındığında **20**; **50** alındığında **260**; **500** alındığında **3000**. Elli
işlemelik planın nesne bedeli on işlemeliğin on üç katıdır, oysa işleme sayısı yalnız beş
katıdır — aradaki fark plana giren aralığa düşen ikili varlıklardan gelir. Uçtaki işlemeler
bu yüzden ucuzdur ve etkileşimli kipin günlük kullanımı da oradadır: henüz paylaşılmamış son
birkaç işlemeyi düzenlemek.

Üç tablo birlikte okunduğunda tek bir kural veriyor: **planı uca yakın tut.** Kuralın hem
bedel hem de risk tarafı vardır. Bedel tarafı ölçüldü — üç işlemelik plan altı nesneye,
beş yüz işlemelik plan üç bin nesneye dokunuyor. Risk tarafı henüz ölçülmedi: plana giren
aralık ne kadar geriye uzanırsa, o aralıktaki işlemelerin başkaları tarafından çoktan
alınmış olma olasılığı da o kadar yükselir. İki taraf da aynı yöne bakar ve ikisi de aynı
şeyi söyler; ölçülen ikincisi bu konunun üçüncü dersinde gelir.

## Yeniden Yazmadan Önce

Yeniden yazma geri alınabilir bir işlem değildir; eski zincirin erişilemez kalması, onu geri
getirmenin bir yolu bulunmadığı anlamına gelmez ama bir yolu **arayacağınız** anlamına gelir.
Üç alışkanlık bu aramayı gereksiz kılar.

**Yedek dal.** İşlemden önce dalın o anki ucunu gösteren bir dal açmak tek satırdır ve
kurtarmayı bir işaretçi geri almaya indirger. Yedek dal yerel bir kayıt değildir; olağan bir
daldır, silinene kadar durur.

**Kuru çalışma.** Planı uygulamadan önce iki zincirin ne kadar ayrıştığını gösteren
karşılaştırma yetenekleri vardır. Yeniden yazılmış zincir ile yedeği yan yana konduğunda
hangi işlemenin gerçekten değiştiği, hangisinin yalnız kimlik değiştirdiği okunur.

**Ayrı klon.** Toplu bir dönüşüm denenecekse deponun ayrı bir kopyası üzerinde denenir. Bu,
sonraki dersin konusudur ve orada zorunlu bir adım hâline gelir.

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

$ git branch yedek/olcum olcum
$ git rebase -i --onto ana 9c4d7e1 olcum
$ git range-diff ana...yedek/olcum ana...olcum
```

Dördüncü güvence **referans günlüğüdür (reflog)**: araç dal ucunun her hareketini yerel bir
günlüğe yazar ve eski uç oradan okunabilir. Günlüğün iki sınırı vardır — yereldir ve
süresizce saklanmaz. Bu konunun dördüncü dersi tam olarak o sınırı ölçer: yeniden yazmadan
sonra kaç işlemenin erişilebilir kaldığını ve kurtarma penceresinin ne zaman kapandığını.

## Özet

- Bir işlemenin kimliği öncülünün kimliğini içerir; bu yüzden bir işlemeyi değiştirmek
  **ondan sonraki her işlemenin** kimliğini değiştirir. Bedeli belirleyen, değişikliğin
  büyüklüğü değil **yeridir**.
- Etkileşimli kip işlemeleri bir plan listesine alır; dört eylem yeniden adlandırma, sıra
  değiştirme, sıkıştırma ve atmadır.
- Aynı konumda dört eylem de **501** işlemenin kimliğini değiştirir ve **3002** nesneye
  dokunur; ayrışan tek şey sonuçtaki işleme sayısıdır (**999** ya da **1000**).
- Ortadan yeniden yazmak dört ölçekte **252 / 362 / 3002 / 11322** nesneye dokunur ve oran
  **0,520 / 0,505 / 0,501 / 0,500**'de kalır: yeniden yazma oransal olarak ucuzlamaz.
- Plana alınan işleme sayısı bedeli doğrudan belirler: **3 / 10 / 50 / 500** işlemelik
  planlar sırasıyla **6 / 20 / 260 / 3000** nesneye dokunur.
- Yeniden yazma geri alınamaz; yedek dal, kuru çalışma ve ayrı klon üç güvencedir.

## Sonraki Adım

Bu derste yeniden yazma tek bir dalın son birkaç işlemesinde kaldı ve en derin denemesi bile
tarihçenin ortasından başladı. Bazen gereken bundan geniştir: bir dosyanın tarihçedeki her
sürümünün çıkarılması, bir yazar alanının bütün işlemelerde düzeltilmesi, bir dizinin köke
taşınması. Bu işlerin ortak yanı, tarihçenin **ilk** işlemesinden başlamak zorunda
olmalarıdır. Sonraki ders bu genişlemenin bedelini ölçer: bin işlemelik bir tarihçede ilk
işlemeden başlayan bir dönüşüm kaç kimliği değiştirir, kaç nesneye dokunur, ve işlem
tamamlandıktan sonra deponun kopyalarına ne olur.
