---
id: 773766eac9e6ff3c46bd686d78539aed
author: Lemon Mint
title: 'İnsanlar ve Kodlama Ajanları İçin CAS Temelli Bir Mimari: Git Monorepo''sunu Yeniden Düşünmek'
description: Parentless trunk snapshot'ları, izole çalışma alanı referansları, bellek içi birleştirme ağaçları, hiyerarşik OWNERS dosyaları ve O(delta) ayna senkronizasyonu kullanarak, standart Git üzerinde sıfır daemon'lu, CAS-native bir monorepo nasıl oluşturulur?
language: tr
date: 2026-10-30T01:17:15.292299Z
path: /blog/posts/rethinking-the-git-monorepo-a-cas-native-architecture-for-humans-and-coding-agents-zfd3d7931
category: lowlevel
---

Büyüyen her mühendislik organizasyonu er ya da geç çok sayıda depo ile tek depo arasında bir seçim yapar. Küçük depoların onlarcasıyla başlayınca hayat ilk başta basit görünür. Her kütüphanenin kendi issue tracker'ı, kendi CI pipeline'ı ve saniyeler içinde tamamlanan bir `git clone` işlemi vardır. Ardından çekirdek bir ağ paketindeki bir struct'ı değiştirirsiniz ve günün geri kalanını altı downstream depoda sürüm güncelleme pull request'leri açarak, CI kuyruklarının topolojik sırayla boşalmasını bekleyerek geçirirsiniz.

Her şeyi geleneksel bir Git monorepo'suna taşırsanız, depolar arası koordinasyonu depo boyutuyla takas etmiş olursunuz. Commit geçmişi derinleştikçe ve geçmiş revizyonlarda ikili varlıklar birikdikçe `git fetch` yavaşlar. Çalışma ağaçları gigabaytlara şişer. Kısa süre sonra, yalnızca günlük geliştirmeyi katlanılabilir tutmak için özel bir sanal dosya sistemi daemon'ı, özel bir kod inceleme sunucusu ya da bir uzak build worker filosu kurulması önerilir.

Otonom kodlama ajanları ekibe katıldığında, her iki başarısızlık modu da kötüleşir. Polyrepo'lar bir ajanı projeler arası çağıranlara karşı kör bırakır ve onu depolar arasında kimlik bilgilerini yönetmeye zorlar. Geleneksel monorepo'lar ise her görev başlatmada ajanın konteyner diskini ve ağ bant genişliğini tüketir; aynı dalda çalışan eşzamanlı ajanlar ise bitmek bilmeyen rebase yarışları yaratır.

`google3` mimarisinden ilham alarak tek gövdeli (single-trunk) atomik değişiklikler, saniyenin altında seyrek (sparse) onboarding, hiyerarşik `OWNERS` yönetişimi ve standart Git altyapısı ile sıradan nesne depolaması kullanan bağımsız açık kaynak aynaları geliştirdik.

Tasarım ne özel bir dosya sistemi daemon'ına ne de üçüncü taraf bir inceleme cihazına ihtiyaç duyar; çünkü Git'i bir Merkle-tree Content-Addressable Store (CAS) olarak ele alır.

## Yavaş Git Monorepo'larının Kalbindeki Yanılgı

Geliştiriciler Git'in büyük monorepo'lara ölçeklenmediğinden yakındığında, nadiren Git'in nesne veritabanındaki bir sınıra çarpmaktadırlar. `.git/objects` içinde Git, SHA-1 (veya SHA-256) içerik karmasıyla anahtarlanmış üç değişmez ilkel veri saklar:

1. **`blob`**: Tek bir dosyanın ham bayt içeriği.
2. **`tree`**: Dosya adlarını ve izinlerini `blob` ya da alt `tree` karmalarına eşleyen bir dizin listesi.
3. **`commit`**: Tek bir kök `tree` karmasına, sıfır veya daha fazla üst `commit` karmasına ve yazar meta verisine işaret eden küçük bir metin başlığı (genellikle 200 ila 300 bayt).

Bir monorepo 50.000 dosya içeriyorsa ve bir dosyada tek bir satırı düzenlerseniz, yeni commit diğer 49.999 dosyanın tam `blob` ve `tree` karmalarını yeniden kullanır.

Geleneksel bir Git monorepo'su ağır hissettirir, çünkü gelenek tek bir referansa, `refs/heads/main`'e, birbiriyle çelişen üç işi yükler:

- Her projenin **tüm birleşik dizin ağacını** tutar.
- İlk güne kadar uzanan **tüm üst-bağlantılı geçmiş commit zincirini** sürükler.
- Git sunucularının her `git clone` ve `git fetch` sırasında varsayılan olarak duyurduğu ve müzakere ettiği ad alanı olan `refs/heads/*` içinde yer alır.

Bir geliştirici ya da CI runner'ı her `refs/heads/main` getirdiğinde, istemci ve sunucu binlerce tarihsel revizyon boyunca commit grafiği erişilebilirliğini müzakere eder. Biri üç yıl önce yanlışlıkla 100 MB'lık bir arşiv commit edip ertesi gün silmişse, onun `blob`'u hâlâ `refs/heads/main`'den erişilebilir bir tarihsel `tree`'ye bağlıdır.

## Referans Ad Alanını Ayırmak

Git'in wire protokolü, standart bir clone sırasında yalnızca `refs/heads/*` ve `refs/tags/*` referanslarını duyurur. `refs/trunk/*` ya da `refs/ws/*` gibi özel ad alanları altındaki referanslar sunucuda tam olarak aynı nesne deposunda yaşar, aynı packfile delta sıkıştırmasından yararlanır ve açıkça getirilebilir ya da itilebilir; yine de varsayılan clone'lara sıfır ek yük getirmez.

Tek bir depodaki bu işleri ayrı referanslara bölmek darboğazı ortadan kaldırır:

```
refs/heads/main               Yalnızca kontrol düzlemi (~20 KB: kurallar, .gitconfig, senkronizasyon yapılandırması, betikler)
refs/trunk/main               En son birleşik kök tree'ye işaret eden, üst öğesi olmayan snapshot commit
refs/trunk/history            Tam olarak aynı kök tree SHA-1'ini paylaşan doğrusal üst-bağlantılı commit zinciri
refs/ws/<actor>/<id>          Geliştirici veya ajan başına izole çalışma alanı snapshot'ları (changelist'ler)
refs/ws/cl/<change-id>/<tip>  Değişmez patchset'ler: inceleme için gönderilen bir değişikliğin her ucu
refs/heads/land/<id>          Ana dala alınır alınmaz silinen geçici merge-queue tetikleyicisi
```

### 1. Kontrol Düzlemi (`refs/heads/main`)

Varsayılan dal hiçbir uygulama kaynak kodu içermez. Yalnızca depo işletim kurallarını (`AGENTS.md`, `README.md`), iş akışı takma adlarından oluşan ortak bir `.gitconfig`'i, Starlark senkronizasyon yapılandırmasını (`sync.star`) ve sunucu tarafı birleştirme betiklerini izler. Varsayılan dalı clone'lamak yaklaşık 20 KB aktarır ve milisaniyeler içinde tamamlanır.

### 2. Üst Öğesiz Trunk Snapshot'ı (`refs/trunk/main`)

`refs/trunk/main`, tüm organizasyonun (`//web/*`, `//net/*`, `//ipc/*`, `//storage/*`, `//crypto/*`, `//ai/*`, `//devtools/*`, `//corp/*`, `//third_party/*`, `//experimental/*`) eksiksiz, birleşik kaynak ağacına işaret eder; ancak commit nesnesi **`-p` üst bayrağı olmadan** oluşturulur.

`refs/trunk/main`'in sıfır üst öğesi olduğundan (`parents = []`), onu getirmek sıfır commit grafiği müzakeresi gerektirir. Git sunucusu geçmişi taramaz; tek başlık commit'i ve geçerli dizin `tree` nesnelerini gönderir. Geçen aya ait tarihsel ikili dosyalar ya da silinmiş dosyalar `refs/trunk/main`'den erişilemez ve hiçbir zaman aktarılmaz.

### 3. Doğrusal Denetim Geçmişi (`refs/trunk/history`)

Geliştiricilerin regresyonları incelerken yine de `git blame` ve `git log` komutlarına ihtiyacı vardır. Her değişiklik ana dala alındığında birleştirme betiği, **tam olarak aynı kök `$NEW_TREE` SHA-1 karmasına** işaret eden iki commit nesnesi oluşturur:

```bash
# Anlık derinlik-1 çalışma alanı checkout'ları için üst öğesiz snapshot commit
SNAP=$(git commit-tree "$NEW_TREE" -m "$RAW_MSG")

# Doğrusal git log ve git blame için üst-bağlantılı commit
HIST=$(git commit-tree "$NEW_TREE" -p "$OLD_HIST" -m "$RAW_MSG")

git push --atomic origin \
  --force-with-lease="refs/trunk/main:${OLD_MAIN}" \
  --force-with-lease="refs/trunk/history:${OLD_HIST}" \
  "${SNAP}:refs/trunk/main" \
  "${HIST}:refs/trunk/history"
```

Hem `refs/trunk/main` hem de `refs/trunk/history` tutmak depolama ayak izini ikiye katlamaz. Her iki commit de aynı `$NEW_TREE` karmasına başvurduğundan, Git'in içerik adresli deposu `tree` ve `blob` nesnelerinin %100'ünü tekilleştirir. Üst öğesiz snapshot'ın ek depolama maliyeti yalnızca 250 baytlık bir commit başlığıdır.

### 4. İzole Çalışma Alanları (`refs/ws/<actor>/<id>`)

Üzerinde çalışılan dallar `refs/heads/*` yerine `refs/ws/<actor>/<id>` altına itilir. Yüzlerce kodlama ajanı her dakika kontrol noktası kaydedebilir; dal açılır listelerini kirletmeden ya da insan mühendisler için `git fetch` işlemini yavaşlatmadan.

## Dört Adımda Onboarding: Seyrek + Blobsuz Checkout Nasıl Çalışır

Bu referans düzeniyle yeni bir geliştirici ya da geçici bir kodlama ajanı konteyneri özel bir CLI ya da FUSE sürücüsü kurmaz. Onboarding, standart Git ve deponun takma adlarıyla dört adımda tamamlanır:

```bash
# 1. Blob filtreleme ve seyrek mod etkinleştirilmiş şekilde 20 KB'lık kontrol düzlemini clone'layın
git clone --filter=blob:none --sparse https://github.com/example-org/monorepo.git
cd monorepo

# 2. Depo takma adlarını yükleyin ve refs/trunk/* referanslarını ekleyin
git config include.path ../.gitconfig
git trunk-init

# 3. Bu görev için gereken alan dizinlerini bildirin
git sparse-checkout set net/relay ipc/codec

# 4. En son trunk snapshot'ına köklenmiş izole bir çalışma alanı oluşturun
git ws-new alice/optimize-framing
```

Her adım yalnızca ihtiyaç duyduğunu getirir:

1. `git clone --filter=blob:none --sparse`, `refs/heads/main` üzerindeki 20 KB'lık kontrol düzlemini indirir.
2. `git trunk-init`, `+refs/trunk/*:refs/remotes/origin/trunk/*` yapılandırır ve blobsuz bir fetch çalıştırır. Git, `refs/trunk/main` için `tree` meta verisini (genellikle birkaç on kilobayt) indirir ve **sıfır dosya blob'u** indirir.
3. `git sparse-checkout set net/relay ipc/codec`, Git'in cone-mode indeks filtresine yalnızca kök dizini ve bu iki alt ağacı somutlaştırmasını söyler.
4. `git ws-new`, `origin/trunk/main`'e köklenmiş yeni bir dala geçer. Git bundan sonra yalnızca `net/relay` ve `ipc/codec` içindeki `blob` nesnelerini talep üzerine ister. Monorepo'nun kalan %95'i asla diske indirilmez.

### Gelecek Ufku: `refs/trunk/main`'i Sanal Dosya Sistemi (VFS) Olarak Bağlamak

Blobsuz clone'larla seyrek checkout, ek istemci araçları olmadan günlük iş akışlarını karşılar. `refs/trunk/main` zaten Content-Addressable Store içinde saf bir Merkle ağacı olduğundan, mimari ayrıca Linux'ta FUSE, macOS'ta FileProvider ya da Windows'ta ProjFS aracılığıyla isteğe bağlı bir kullanıcı alanı Sanal Dosya Sistemi (VFS) için doğrudan bir temel sağlar:

1. **Anlık Tam Ağaç Bağlama**: Hafif bir yerel bağlama daemon'ı `refs/trunk/main`'in kök `tree` nesnesini okur ve tüm monorepo dizin hiyerarşisini milisaniyeler içinde çalışma dizinine yansıtır; `git sparse-checkout set` çalıştırma gereksinimini ortadan kaldırır.
2. **Talep Üzerine Blob Yükleme (On-Demand Blob Faulting)**: Dosya içerikleri, bir derleyici, IDE ya da ajan bir `open(2)` ya da `read(2)` sistem çağrısı yapana kadar sanal kalır. Daemon bunun üzerine ilgili SHA-1 `blob`'unu CAS uç noktasından getirir ve yerel NVMe depolamada önbelleğe alır.
3. **Çalışma Alanları için Kopyala-Yaz Katmanı (Copy-on-Write Overlay)**: Yerel düzenlemeler hafif bir üst overlay katmanına yazılır. `git ws-save` çalıştırmak yalnızca bu overlay'deki kirli yolların karmasını alır, güncellenmiş `blob` ve `tree` nesnelerini yazar ve ortaya çıkan commit'i değiştirilmemiş dizinleri taramadan `refs/ws/<actor>/<id>`'ye iter.

## Saf Git Üzerinde Changelist Modeli: Bellek İçinde Sunucu Tarafı Landing

Geleneksel bir Git iş akışında, bir özellik dalını birleştirmek ya iki üst öğeli bir merge commit oluşturur ve geçmişi doğrusal olmaktan çıkarır ya da geliştiricilerin manuel olarak rebase yapıp `main`'e eşzamanlı itmelerle yarışmalarını gerektirir.

`google3` Changelist (CL) modelinden ilham alan mimarimizdeki her çalışma alanı, trunk snapshot'a karşı **tek bir atomik değişikliği** temsil eder. `ws/alice/optimize-framing` içinde yerel olarak çalışırken bir geliştirici ya da ajan on artımlı commit yapabilir (`wip`, `fix tests`, `lint`). Değişiklik ana dala alınmaya hazır olduğunda sunucu, CI runner'ında hiçbir zaman bir çalışma dizini checkout etmeden çalışma alanı deltasını tek bir doğrusal trunk revizyonuna indirger.

Landing betiğinin (`land.sh`) Git 2.40+ altyapısını kullanarak bellekte nasıl çalıştığı aşağıdadır:

```bash
# 1. Çalışma alanının dallandığı kök snapshot commit'ini belirleyin
BASE=$(git rev-list --max-parents=0 "$WORK_SHA")

BASE_TREE=$(git rev-parse "${BASE}^{tree}")
MAIN_TREE=$(git rev-parse "${OLD_MAIN}^{tree}")
WORK_TREE=$(git rev-parse "${WORK_SHA}^{tree}")

# 2. Çalışma ağacı checkout'u olmadan birleştirilmiş kök tree'yi bellekte hesaplayın
if [ "$MAIN_TREE" = "$BASE_TREE" ]; then
  NEW_TREE="$WORK_TREE"
elif OUT=$(git merge-tree --write-tree --merge-base="$BASE_TREE" "$MAIN_TREE" "$WORK_TREE"); then
  NEW_TREE=$(head -n1 <<<"$OUT")
else
  echo "Merge conflict detected; run git ws-sync to rebase." >&2
  exit 1
fi
```

2. adımda:

- Çalışma alanı dalında kaç yerel commit yapıldığına bakılmaksızın betik yalnızca üç tree karmasını karşılaştırır: özgün temel snapshot (`$BASE_TREE`), mevcut trunk snapshot'ı (`$MAIN_TREE`) ve nihai çalışma alanı tree'si (`$WORK_TREE`).
- Alice `//net/relay`'i düzenlerken `refs/trunk/main` `//web/blog`'da ilerlediyse, `git merge-tree --write-tree` birleşik kök tree `$NEW_TREE`'yi doğrudan Git nesne deposunda milisaniyeler içinde hesaplar; runner'ın dosya sistemine dosya yazmadan.
- Aşağıdaki politika kontrolleri geçtikten sonra, `--force-with-lease` ile tek bir `git push --atomic` `refs/trunk/main`'i günceller ve `refs/trunk/history`'ye bir doğrusal commit ekler; landing tetikleyicisi `refs/heads/land/<id>` silinir.

## Mimari Sınırları Uygulamak: Dört Katmanlı Görünürlük ve Hiyerarşik `OWNERS`

Kodu tek bir depoda birleştirmek, alanlar arası sınırlar bir commit ana dala alınmadan önce mekanik olarak zorunlu kılındığında işe yarar. `git merge-tree --write-tree` `$NEW_TREE`'yi ürettikten hemen sonra (ve `git push --atomic` trunk'ı güncellemeden önce), politika motorumuz `git diff-tree "$MAIN_TREE" "$NEW_TREE"` üzerinde iki O(delta) kontrolü çalıştırır.

### 1. Dört Katmanlı Alan Görünürlüğü

Kök tree dört görünürlük katmanına bölünmüştür:

| Dizin Öneki                                                                            | Katman            | İzin Verilen İmportlar                           | Yasaklanan İmportlar           | `OWNERS` Kapısı         |
| :------------------------------------------------------------------------------------- | :---------------- | :----------------------------------------------- | :----------------------------- | :---------------------- |
| `//web/*`, `//net/*`, `//ipc/*`, `//storage/*`, `//crypto/*`, `//ai/*`, `//devtools/*` | Genel Üretim      | Genel Üretim, `//third_party/*`                  | `//corp/*`, `//experimental/*` | Zorunlu                 |
| `//third_party/*`                                                                      | Harici Tedarikçi  | Kendi kendine yeterli ya da `//third_party/*`    | `third_party` dışındaki tüm alanlar | Zorunlu            |
| `//corp/*`                                                                             | Kurumsal Özel     | Genel Üretim, `//corp/*`, `//third_party/*`      | `//experimental/*`             | Zorunlu                 |
| `//experimental/<actor>/*`                                                             | Sandbox           | `corp` olmayan herhangi bir paket                | `//corp/*`                     | Muaf (otomatik onaylı)  |

`//web/*` içindeki genel bir paket `//corp/*` içindeki dahili bir paketi ya da `//experimental/*` içindeki mezun olmamış bir prototipi içe aktarmaya çalışırsa, landing işi `refs/trunk/main`'e dokunmadan iptal edilir.

### 2. Gerrit Sunucusu Olmadan Hiyerarşik `OWNERS` Doğrulaması

Doğrulayıcı, miras kurallarıyla dizin düzeyinde `OWNERS` dosyalarını uygular:

- `$MAIN_TREE` ile `$NEW_TREE` arasında değiştirilen her yol için doğrulayıcı, dosyanın dizininden `//OWNERS`'a kadar yukarı doğru yürür.
- Herhangi bir `OWNERS` dosyası, üst dizinlerden gelen miras onayları engellemek için `set noparent`, ya da onayları dosya adı glob'una göre kapsamak için `per-file *.sql=@dba-team` bildirebilir.
- **Kurcalama Karşıtı Değişmez Kural**: Mevcut `OWNERS` dosyaları her zaman `$MAIN_TREE`'den (mevcut trunk tree) okunur, asla `$NEW_TREE`'den okunmaz. Onaylanmamış bir yazar, aynı çalışma alanı commit'inde `OWNERS` düzenleyerek kendisine izin veremez.
- **Sandbox Muafiyeti**: `//experimental/<actor>/*` altındaki herhangi bir yol `OWNERS` kontrollerini atlar; böylece mühendisler ve ajanlar `git ws-exp <actor> <project>` ile serbestçe prototip yapabilir ve daha sonra `git ws-graduate` ile paketi üretim alanına terfi ettirebilir.

## Sürtünmesiz Kod İncelemesi: Geçici PR'lar ve Snapshot Diff'leri

`refs/heads/main` yalnızca kontrol düzlemini tuttuğundan ve `refs/trunk/main` üst öğesiz bir commit olduğundan, bir çalışma alanı dalından doğrudan `main`'e standart bir GitHub Pull Request açmak ilişkisiz geçmişleri karşılaştırmaya çalışırdı. Bunu farklı değişikliklere göre uyarlanmış üç inceleme iş akışıyla çözdük:

1. **Anlık İki Nokta Çalışma Alanı Diff'leri (`git ws-save` + Kenar Diff Yönlendiricisi)**
   `git ws-save` ile bir çalışma alanını göndermek, `refs/ws/<actor>/<id>`'yi hafif bir kenar worker'ı aracılığıyla açığa çıkarır. Bu worker, `refs/trunk/main` ve çalışma alanı referansını commit SHA'larına çözümler ve GitHub'ın iki nokta karşılaştırma görünümüne (`/compare/<trunk-sha>..<ws-sha>`) yönlendirir. Küçük yamalar ya da ajan tarafından üretilen değişiklikler için incelemeciler diff'i inceleyebilir ve web arayüzünde doğrudan **Land** tıklayabilir.
2. **Geçici GitHub Pull Request'leri (`git ws-pr`)**
   GitHub'da satır satır inceleme için `git ws-pr`, kök snapshot commit'ini (`$(git rev-list --max-parents=0 HEAD)`) `refs/heads/base/<id>`'ye ve çalışma alanı ucunu `refs/heads/review/<id>`'ye iter. Ardından `review/<id>`'yi `base/<id>` ile karşılaştıran bir GitHub Pull Request açar. Temel dal, çalışma alanının dallandığı snapshot olduğundan GitHub'ın **Files changed** sekmesi yalnızca çalışma alanı deltasını gösterir. İncelemeci **Merge pull request** tıkladığında bir webhook, head commit'i `refs/heads/land/<id>`'ye yükseltir, bellek içi landing hattını çalıştırır ve hem `refs/heads/base/<id>` hem de `refs/heads/review/<id>`'yi otomatik olarak siler.
3. **Harici Ayna Pull Request'leri**
   Açık kaynak katkıda bulunanların monorepo iş akışını öğrenmesi hiçbir zaman gerekmez. Her zamanki gibi fork'lar oluşturur ve bağımsız ayna depolarına karşı pull request açarlar.

### Değişiklikler, Patchset'ler ve Onay Taşıması

Bir dal adı bir değişikliği tanımlayamaz. Bir ajan, ana dala alınmadan önce dalını yeniden adlandırabilir, ucunu amend edebilir ya da daha yeni bir trunk'a birkaç kez rebase yapabilir. Gerrit'te olduğu gibi iş akışı, değişikliği ucun commit mesajındaki `Change-Id: I<40 hex>` trailer'ı ile tanımlar. `git ws-save`, `git ws-pr` ve `git ws-land` ucda trailer yoksa ekler, varsa korur; böylece kimlik amend, rebase ve yeniden adlandırmalardan sağ çıkar. Ana dala alınan trunk commit'i trailer'ı korur ve inceleme pull request'inin numarasını kaydeder; böylece `git trunk-cl <number|Change-Id>` onu `refs/trunk/history` içinde bulur.

İncelemeye gönderilen her uç bir patchset olur. `git ws-pr` onu, inceleme dallarının yanında değişmez `refs/ws/cl/<change-id>/<tip>` referansına iter. Bir amend ya da `git ws-sync` sonrasında `git ws-pr`'ı yeniden çalıştırmak aynı pull request'e bir patchset ekler. `git ws-ps` mevcut değişikliğin patchset'lerini listeler ve `git ws-psdiff <a> <b>` iki patchset arasındaki interdiff'i yazdırır; böylece incelemeci yalnızca son turdan bu yana değişeni okur.

GitHub bir onayı tek bir commit'e bağlar, bu nedenle her rebase normalde yeni bir inceleme gerektirir. Landing hattı ayrıca aynı değişikliğin başka bir patchset'ine verilen onayı kabul eder; her iki patchset de kendi temel snapshot'larına aynı yamayı uyguladığında. Bunu tam ikili diff üzerinde `git patch-id --verbatim` ile karşılaştırarak kontrol eder. Daha yeni bir trunk'a temiz bir rebase, başka bir inceleme olmadan ana dala alınır; ancak boşluk ya da dosya modu değişikliği dahil her içerik düzenlemesi yeni bir onay gerektirir.

## O(delta) Çift Yönlü Senkronizasyon ve Ayrı Üretim Dalları

Birçok kuruluş, dış kullanıcıların monorepo'ya dokunmadan `go get`, `cargo install` ya da tek bir projeyi fork'layabilmesi için bireysel paketleri bağımsız GitHub depoları olarak yayımlar. Statik bloglar ya da sürüm kapılı web uygulamaları gibi bazı projeler de `main` yanında ayrı bir `production` dalını sürdürür.

Starlark senkronizasyon motorumuz hem dışa aktarımları hem de gelen katkıları, monorepo'nun boyutuyla değil bir commit'te değişen dosya sayısıyla orantılı **O(delta)** zamanda yönetir:

- **Blobsuz İndeks Ekleme (Blobless Index Splicing)**: Bir ayna deposunun alt ağacını monorepo kök tree'sine eklerken ya da çıkarırken motor `GIT_NO_LAZY_FETCH=1` ayarlar ve `git update-index --index-info` ardından `git write-tree --missing-ok` çalıştırır. Değiştirilmemiş alt ağaçlar ve blob'lar SHA-1 ile referanslanmaya devam eder ve CI runner'ına hiçbir zaman indirilmez.
- **Yalnızca Delta Blob Önceden Getirme**: Dışa aktarılan bir commit'i bağımsız bir aynaya itmeden önce betik `git diff-tree -r --diff-filter=AM "$ext_parent" "$export_tree"` çalıştırır ve yalnızca değiştirilen dosyaların eski ve yeni blob'larını `git cat-file --batch` ile önceden getirir. Git böylece ince bir delta packfile hesaplayıp saniyeler içinde ayna depoya itebilir.
- **İş Akışı ve Sürüm Dalı Koruması**: Dışa aktarma sırasında senkronize edici her bağımsız deponun kendi `.github/workflows/` dizinini korur; böylece genel CI runner'ları projenin testlerini ayna üzerinde çalıştırır. Starlark yapılandırmasındaki her iş akışı `main` gibi açık bir dalı hedefler; bu, ayrı bir `production` dalından dağıtım yapan depolar için sürüm kapılarını korur. Monorepo landing'leri ayna'nın `main` dalıyla senkronize olur ve `main` üzerindeki otomatik meta veri ya da çeviri commit'leri webhook aracılığıyla `refs/trunk/main`'e geri senkronize olur. `main`'in `production`'a terfi ettirilmesi açık bir sürüm adımı olarak kalır.

## Kapanış Düşünceleri

Bu mimari, Git'in nesne deposunu bir Content-Addressable Store olarak ele alır, `refs/heads/main`'i `refs/trunk/main` ve `refs/trunk/history`'den ayırır, her değişikliği değişmez patchset'lerle birlikte bir `Change-Id` ile tanımlar ve `git merge-tree --write-tree` ile ağaçları bellekte birleştirir. Onboarding maliyeti bir görevin ihtiyaç duyduğu dizinlerle birlikte artar; landing ve ayna senkronizasyon maliyeti ise depo boyutuyla değil, değişikliğin boyutuyla birlikte artar.
