---
title: Kancalar
source: 'https://academia.sh/tr/kurslar/ileri-git/kancalar'
course: 'İleri Git'
language: tr
updated: '2026-08-17T18:10:42+00:00'
license: 'CC BY-SA 4.0'
---

# Kancalar

Kanca bir olay noktasıdır ve engelin konduğu an bedeli belirler: işlemeden önce durdurulan değişiklik sıfır nesneye dokunur, itmeden önce on işleme ve 140 nesne, kabulden altı yüz işleme sonra 601 işleme, 3522 nesne ve yedi kopyanın yedisi.

Önceki iki ders tarihçeye sonradan soru sordu: kusur çoktan girmiş, satır çoktan
yazılmıştı. Araçlar olmuş bitmiş bir kaydı okudu ve bedeli okuma tarafında ödedi.

Bir değişiklik ise tarihçeye tek adımda girmez. Önce çalışma alanında durur, sonra hazırlık
alanına alınır, sonra bir işleme olur, sonra itilir, sonra karşı taraf onu kabul eder. Bu
anların her biri bir **kapıdır** ve her kapıya bir denetim yerleştirilebilir. **Kanca
(hook)**, aracın bu anlardan birinde çalıştırdığı programdır; çıkış kodu sıfırdan farklıysa
kimi kapılarda işlem durur. Bu dersin sorusu kancanın ne yaptığı değil: engelin **hangi
kapıya** konduğuna göre bedelin nasıl değiştiği, ve o bedeli kimin ödediği.

## Kanca Bir Olay Noktasıdır

Kanca, deponun kendi dizini içinde belirli adlarla duran çalıştırılabilir dosyalardan
ibarettir. Araç, belirli bir işlemin belirli bir anına geldiğinde o addaki dosyayı arar,
varsa çalıştırır ve çıkış kodunu okur. Ortada bir eklenti düzeneği, bir kayıt defteri ya da
bir yapılandırma dili yoktur; sözleşme yalnızca **dosyanın adı, çalıştırılabilir olması ve
çıkış kodudur.**

Kancaların sürekli tümleştirme hattını tetikleyen kullanımı Sürekli Tümleştirme ve Dağıtım
kursunda kuruldu; orada kanca bir **tetikleyiciydi** ve tartışılan şey hattın kendisiydi. O
tartışma burada tekrarlanmıyor. Bu derste kanca bir **yerel olay noktasıdır** ve ölçülen
tek şey, o noktada hangi işlemin hâlâ durdurulabildiğidir.

İki sınıf vardır ve aralarındaki fark dersin sonucunu belirler. **İstemci tarafı kancalar**
çalışanın kendi deposunda, işlemeden ve itmeden önceki anlarda çalışır. **Sunucu tarafı
kancalar** karşı tarafta, itilen değişiklikler kabul edilmeden önce çalışır. Birincisi
deponun tarihçesinde taşınmaz — klonlama kancaları getirmez — ikincisi ise deponun
tarihçesinden bağımsız olarak her zaman çalışır.

## Kapıların Sırası

Anlar ve o anlarda çalışan kancalar aşağıdaki sırayı izler. Yalnız bir bölümü engelleme
yetkisi taşır; kalanı olup bittikten sonra haber verir.

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

pre-commit        işleme kurulmadan önce      — engelleyebilir
commit-msg        mesaj yazıldıktan sonra     — engelleyebilir
post-commit       işleme kurulduktan sonra    — engelleyemez
pre-push          itme başlamadan önce        — engelleyebilir
pre-receive       karşı taraf kabul etmeden   — engelleyebilir
update            her başvuru için ayrı ayrı  — engelleyebilir
post-receive      kabul tamamlandıktan sonra  — engelleyemez

# .git/hooks/pre-commit
#!/bin/sh
if git diff --cached --name-only | grep -q '\.bin$'
then
    echo "ikili varlık hazırlık alanında; işleme durduruldu" >&2
    exit 1
fi
exit 0

# örnek döküm
$ git commit -m "sunum yenilendi"
ikili varlık hazırlık alanında; işleme durduruldu
```

Sıradaki iki ayrım önemlidir. `post-` önekli kancalar bir kararı değiştiremez; iş olmuştur
ve kanca yalnız haber verir. Ve istemci tarafındaki her engelleyici kanca, komuta verilen
bir seçenekle atlanabilir — bu bir kusur değil, tasarımdır: yerel kanca çalışanın kendi
kolaylığı içindir, bir yaptırım düzeneği değil.

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

- **TA33** — Tarihçe ortak kurgudan üretilir ve bin işlemedir; kurgu ve kâhin
  değiştirilmez.
- **TA34** — Engellenmesi istenen değişiklik **400**. işlemededir. Tek bir değişiklik
  izlenir; kaç değişikliğin engellendiği sayılmaz.
- **TA35** — Bedelin birimi **dokunulan nesnedir**. Bir işlemeyi tarihçeden çıkarmak,
  ondan sonraki her işlemenin kimliğini değiştirir; dokunulan nesne, kimliği değişen
  işlemelerin taşıdığı nesnelerin toplamıdır.
- **TA36** — İtme **onarlı yığınlar** hâlinde yapılır. İtmeden önceki ve sunucudaki
  kancalar bu yüzden dokuz işleme sonra devreye girer.
- **TA37** — Kabul edildikten sonra fark ediliş iki noktada ölçülür: yüz işleme sonra ve
  altı yüz işleme sonra.
- **TA38** — Deponun **yedi** kopyası vardır. Yayımlanmamış bir değişiklik hiçbir kopyayı
  ilgilendirmez; yayımlanmış bir değişikliğin geri alınması kopyaların tümünü ilgilendirir.
- **TA39** — İkinci bölümde tek değişen şey ölçektir. Kancanın çalışma sayısı ile
  incelediği işleme sayısı ayrı ayrı sayılır; kancanın kendi süresi ölçülmez.

## Ölçüm

```python
"""Kancanin ani: o anda hangi isleme hala engellenebilir.

Bolum 1 - engel bes ayri anda konursa geri almanin bedeli.
Bolum 2 - kancanin kendi bedeli: kac kez calisir, kac isleme inceler.
"""
TOHUM = 20260814
DOSYALAR = ("olcum.py", "rapor.py", "kimlik.py", "ayar.py", "belge.md")
KOPYA, KONUM, YIGIN = 7, 400, 10


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 geri_alma(t, konum, farkedis):
    """konum'daki isleme farkedis'te fark edilirse yeniden yazilacak kume."""
    if farkedis is None:
        return 0, 0
    araya = [x for x in t if konum <= x["no"] <= farkedis]
    return len(araya), sum(x["nesne"] for x in araya)


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


OLAYLAR = (
    ("işlemeden önce", "evet", None, 0),
    ("itmeden önce", "evet", KONUM + YIGIN - 1, 0),
    ("sunucu kabulünde", "evet", KONUM + YIGIN - 1, 0),
    ("kabulden yüz işleme sonra", "hayır", KONUM + 100, KOPYA),
    ("kabulden altı yüz sonra", "hayır", KONUM + 600, KOPYA),
)

t = tarihce(1000)
print(f"{'engelin konduğu an':>26s} {'engelleyebilir':>14s} "
      f"{'yeniden yazılan':>16s} {'dokunulan nesne':>16s} {'eşitleyen kopya':>16s}")
for ad, engel, farkedis, kopya in OLAYLAR:
    isl, nes = geri_alma(t, KONUM, farkedis)
    print(f"{ad:>26s} {engel:>14s} {isl:16d} {nes:16d} "
          f"{yeniden_esitleyen(kopya, KONUM, t, farkedis):16d}")

print()
print(f"{'işleme':>7s} {'işlemeden önce: çalışma':>24s} {'itmeden önce: çalışma':>22s} "
      f"{'incelenen işleme':>17s}")
for n in (50, 200, 1000, 4000):
    print(f"{n:7d} {n:24d} {n // YIGIN:22d} {n:17d}")
```

```
        engelin konduğu an engelleyebilir  yeniden yazılan  dokunulan nesne  eşitleyen kopya
            işlemeden önce           evet                0                0                0
              itmeden önce           evet               10              140                0
          sunucu kabulünde           evet               10              140                0
 kabulden yüz işleme sonra          hayır              101              522                7
   kabulden altı yüz sonra          hayır              601             3522                7

 işleme  işlemeden önce: çalışma  itmeden önce: çalışma  incelenen işleme
     50                       50                      5                50
    200                      200                     20               200
   1000                     1000                    100              1000
   4000                     4000                    400              4000
```

## Engelin Konduğu An

Üst tablonun birinci satırı ölçümün çıpasıdır. İşleme kurulmadan durdurulan bir değişiklik
tarihçeye **hiç girmez**: yeniden yazılacak işleme **0**, dokunulan nesne **0**, eşitlemek
zorunda kalan kopya **0**. Değişiklik hâlâ çalışma alanındadır ve düzeltilmesi bir dosya
düzenlemesinden ibarettir.

İkinci ve üçüncü satırlarda işleme kurulmuş, üstüne dokuz işleme daha binmiştir. Geri
almanın bedeli **10** işleme ve **140** dokunulan nesnedir. Yayımlanmadığı için eşitleyen
kopya yine **0**; bedel tümüyle yazanın üstündedir ve tarihçe kendi makinesinde yeniden
yazılabilir.

Dördüncü ve beşinci satırlarda kapı kapanmamıştır. Yüz işleme sonra fark edildiğinde geri
alma **101** işlemenin kimliğini değiştirir ve **522** nesneye dokunur; altı yüz işleme
sonra **601** işleme ve **3522** nesne. Ve eşitleyen kopya artık **0** değil, **7**.
Buradaki sıçrama nesne sütununda değil, en sağdaki sütundadır: **dokunulan nesne yirmi beş
kat büyürken, işi kimin yaptığı bir kişiden yedi kopyanın hepsine geçer.**

Ölçümün çözünürlüğü bin işlemelik kümede **1/1000**'dir; ayırt edilebilen en küçük fark
tek bir işlemedir. Birinci satır ile ikinci satır arasındaki **10** işlemelik fark bu
bandın on katıdır ve rahatça taşınır. Dördüncü satırla beşinci satır arasındaki **500**
işlemelik fark ise ölçeğin yarısıdır; bu kümeyle savunulamayacak tek şey, kapılar arasında
birkaç işlemelik ince ayrımlar yapmaktır.

Örüntü şudur: **engelin bedeli engelin konduğu ana göre değil, konmadığı süreye göre
büyür.** Kapılar arasındaki fark birkaç saniye ya da birkaç saattir; bedel arasındaki fark
sıfırdan üç bin beş yüz yirmi ikiye. Ve bu bedel, bir noktadan sonra artık yazanın
ödeyebileceği bir bedel değildir.

## Kabulden Sonrası Neden Ayrı Bir Sınıf

Kabul edilmiş bir işlemeyi tarihçeden çıkarmak, tarihçeyi yeniden yazmaktır ve o işlem bu
kursun ilk konusunda kendi bedeliyle kuruldu: geri alınamaz, her kopyanın yeniden
eşitlenmesini gerektirir ve komutu tam biçimde yazılmaz. Burada eklenen tek şey, o bedelin
neden doğduğudur: **engel bir kapı geç kondu.**

Yayımlanmış bir hatanın tarihçeyi yeniden yazmadan da bir karşılığı vardır: değişikliği
**deviren** yeni bir işleme eklemek. Devirme tarihçeyi bozmaz, kimlik değiştirmez, kopyaları
yeniden eşitlemeye zorlamaz — bu yüzden güvenli yoldur ve önce o denenir. Ama devirme
kaydı düzeltir, **nesneyi silmez**. Bir gizli anahtar ya da yanlışlıkla eklenmiş büyük bir
varlık, devirmeden sonra da tarihçedeki nesneler arasında durmaya devam eder ve klonlayan
herkese gitmeyi sürdürür.

Buradan sunucu tarafı kancanın asıl gerekçesi çıkıyor. Sızmış bir gizli değer, depo
düzeltilerek değil, **değerin kendisi geçersiz kılınarak** kurtarılır; tarihçe temizliği
ancak ondan sonra gelen ikinci bir iştir. Kabul kapısı, bu iki işten hiçbirinin gerekmediği son andır.

## Kancanın Kendi Bedeli

Alt tablo engelin erken konmasının bedava olmadığını gösteriyor. İşlemeden önceki kanca dört
bin işlemelik bir tarihçede **4000** kez çalışır; itmeden önceki kanca onarlı yığınlar
yüzünden **400** kez. İncelenen işleme sayısı ikisinde de **4000**'dir — aynı iş, on kat
farklı sayıda çalışmaya bölünmüş.

Bu bölünmenin bedeli her çalışmanın **sabit maliyetidir**: sürecin başlaması, denetim
aracının yüklenmesi, dizinin taranması. Sabit maliyet incelenen işleme sayısıyla değil,
çalışma sayısıyla çarpılır; erken kapı bu yüzden on katı sabit maliyet öder. Karşılığında
kazandığı şey **geri bildirim mesafesidir**: işlemeden önceki kanca değişikliği üretildiği
anda durdurur, itmeden önceki kanca en kötü durumda dokuz işleme sonra.

İki kapının ölçüde nerede durduğu böylece netleşiyor. Erken kapı ucuz düzeltme ve pahalı
işletme demektir; geç kapı tersi. Yaygın düzen ikisini bölmektir: saniyeler süren ucuz
denetimler işlemeden önceki kapıya, uzun süren pahalı denetimler itmeden önceki kapıya
konur ve yaptırım gerektiren denetimler her iki durumda da kabul kapısında yinelenir.

## Kancanın Neye Baktığı

Bir kancanın hangi anda çalıştığı, aynı zamanda **neyi görebildiğini** belirler. İşlemeden
önceki kanca hazırlık alanının içeriğini görür; çalışma alanındaki kaydedilmemiş
değişiklikleri değil. Bu ayrım gözden kaçtığında kanca yanlış şeyi denetler: çalışma
alanındaki dosyaları okuyan bir denetim, yalnız bir bölümü hazırlığa alınmış bir
değişiklikte hazırlığa girmemiş satırlara da bakar ve işlemeyi geçerken hazırlıktaki içerik
denetimden hiç geçmemiş olur. Doğru kanca hazırlık alanını okur, dosya sistemini değil.

Kabul kapısındaki iki kanca da çözünürlükleriyle ayrılır. Biri itilen yığının tamamı için
bir kez çalışır ve kararı tüm yığına verir: ya hepsi girer ya hiçbiri. Diğeri her başvuru
için ayrı ayrı çalışır ve bir dalı reddedip diğerini kabul edebilir. Ölçümün onarlı yığın
varsayımı burada karşılık buluyor — yığının tamamını reddeden bir kapı, kusurlu tek bir
işleme yüzünden dokuz kusursuz işlemeyi de geri çevirir. Reddedilen dokuz işleme kaybolmaz,
yazanın tarihçesinde durmayı sürdürür; ama yığının yeniden düzenlenmesi gerekir ve bu,
kabul kapısının erken kapılara göre ödettiği ikinci bedeldir.

Kancanın kendisi için iki kural bundan çıkar. Kanca **hızlı** olmalıdır: her çalışmada
saniyeler süren bir denetim, dört bin çalışmada saatlere dönüşür ve sonunda atlanmaya
başlar. Ve kanca **kararlı** olmalıdır: aynı içeriğe iki kez farklı yanıt veren bir denetim,
engellediği kadar geçirir ve hiçbir güvence taşımaz.

## Kimin Kancası Çalışır

Son ayrım dersin sonucudur. İstemci tarafı kancalar deponun tarihçesinde taşınmaz; klonlama
onları getirmez, bir işleme onları yayamaz. Ekibin her üyesi kendi deposuna ayrı ayrı
kurmak zorundadır ve kuran da bir seçenekle atlayabilir. Yani istemci kancası, **yedi
kopyanın kaçında kurulu olduğu bilinmeyen** bir denetimdir.

Bu taşınmazlığın kısmi bir karşılığı vardır. Kancalar deponun içinde izlenen sıradan bir
dizine yazılabilir ve aracın kanca dizini bir ayarla oraya çevrilebilir; böylece kancaların
kendisi tarihçeyle taşınır ve ekip aynı denetimi paylaşır. Ama ayarın kurulması yine her
kopyada ayrı bir adımdır ve atlanabilirlik değişmez. Taşınan şey kancanın **içeriğidir**,
yaptırımı değil — yedi kopyanın kaçında etkin olduğu hâlâ bilinmez.

Sunucu tarafı kancası tersidir: tek bir yerde durur, herkes için aynı biçimde çalışır ve
atlanamaz. Yaptırım gerektiren her kural sonunda oraya yazılmak zorundadır. Ama kabul kapısı
aynı zamanda **engelleyebilen son kapıdır** ve o ana gelindiğinde işleme çoktan kurulmuş,
yazanın tarihçesine girmiş, belki üstüne dokuz işleme daha binmiştir. Ölçümün üçüncü satırı
tam olarak burayı gösteriyor: kabul kapısı engelleyebiliyor, ama engellediğinde bile geri
alma bedeli **10** işleme ve **140** nesnedir.

Sonuç şu ikisinin aynı anda doğru olmasıdır: **yaptırımı olan tek kapı, bedeli sıfırlayan
kapı değildir**; bedeli sıfırlayan kapının ise yaptırımı yoktur. İstemci kancası bu yüzden
bir güvence değil, bir kolaylıktır — kabul kapısında zaten reddedilecek bir şeyi yazana beş
yüz yirmi iki nesne önce söyleyen bir kolaylık.

## Özet

- Kanca bir olay noktasıdır: aracın belirli bir anda çalıştırdığı program ve okuduğu çıkış
  kodu. `post-` önekli kancalar haber verir, karar değiştirmez.
- Engel işlemeden önce konursa değişiklik tarihçeye hiç girmez: **0** işleme, **0**
  dokunulan nesne. İtmeden önce konarsa **10** işleme ve **140** nesne, yayımlanmadığı için
  **0** kopya.
- Kabulden altı yüz işleme sonra fark edilirse geri alma **601** işlemeye ve **3522**
  nesneye dokunur, ve **yedi kopyanın yedisi** yeniden eşitlemek zorunda kalır; bedel
  yazanın üstünden çıkıp herkese dağılır.
- Devirme yayımlanmış bir hatayı tarihçeyi bozmadan karşılar ama nesneyi silmez; gizli bir
  değerin karşılığı önce o değerin geçersiz kılınmasıdır.
- Erken kapı dört bin işlemede **4000** kez, itme kapısı **400** kez çalışır; incelenen
  işleme ikisinde de **4000**'dir. Erken kapı on kat sabit maliyet öder, karşılığında geri
  bildirim mesafesini dokuz işlemeden sıfıra indirir.
- İstemci kancası taşınmaz ve atlanabilir, sunucu kancası atlanamaz ama en geç kapıdır;
  yaptırımı olan kapı bedeli sıfırlayan kapı değildir.

## Sonraki Adım

Bu konu boyunca nesne sayısı hep ölçümün arka planında durdu: aramanın adımını sayarken de,
suçlamanın taramasını sayarken de, kancanın geç kalmasının bedelini sayarken de tarihçe
**tek bir deponun** içindeydi ve nesneler o deponun kendi nesneleriydi. Sonraki konu bu
arka planı öne alıyor: ya nesne sayısı ölçümün zemini değil, **işin kendisi** olursa? Bir
depo başka bir deponun tarihçesini içine aldığında, ya da tek bir dosyanın her sürümü ayrı
bir nesne olarak biriktiğinde, buraya kadar sabit saydığımız arka plan ölçülmesi gereken
şeye dönüşür.
