Yapay zeka ile merge conflict’i güvenle çözmek için önce çakışmayı okunur hâle getir, sonra kodlama ajanına iki tarafın amacını ve net kuralları ver; sonucu da ancak git hiç çakışma işareti kalmadığını doğruladıktan ve testlerin geçtikten sonra kabul et. Claude Code ve Codex gibi ajanlar bu işte gerçekten işe yarar: iki sürümü, ortak atayı ve çevredeki kodu senden hızlı okur, birini seçmek yerine iki değişikliği birleştirebilirler. Tipik hataları da bir o kadar belirgindir: bir tarafın amacı net değilse derlenen tarafı tutar, diğerini haber vermeden atarlar.
Bu rehberde çakışmaların neden çıktığını (ve paralel ajanların neden daha sık çakışma ürettiğini), git status’tan git merge --continue’ya adım adım bir akışı, hazır bir prompt şablonunu, rebase ile merge farkını, git rerere’yi, birleştirme öncesi kontrolü ve çakışmaların çoğunu baştan nasıl önleyeceğini bulacaksın. Git komutları Ekim 2026 itibarıyla git-scm.com’daki resmî belgelerle kontrol edildi.
Merge conflict neden çıkar?
Git iki dalı birleştirirken ikisini de ortak atalarıyla karşılaştırır. Bir dosyanın farklı bölgelerindeki değişiklikler otomatik birleşir. İki taraf da aynı bölgeyi değiştirdiyse Git birini seçemez; durur ve iki sürümü çakışma işaretleri arasında dosyaya yazar. Buna metinsel çakışma denir.
En sık karşılaşacağın türler:
- İçerik çakışması: iki dal aynı dosyanın aynı satırlarını değiştirmiş.
- Değiştir/sil: bir dal dosyayı değiştirmiş, diğeri silmiş ya da taşımış.
- Üretilen dosyalar: iki dalın da yeniden ürettiği lockfile’lar, snapshot’lar, derleme çıktıları ya da çeviri paketleri.
Git’in göremediği bir çakışma daha var: anlamsal çakışma. İki dal farklı dosyalara dokunur, temiz birleşir ama yine de birbirini bozar; örneğin biri bir fonksiyonun imzasını değiştirirken diğeri o fonksiyonu çağıran yeni bir yer ekler. Bunu ancak birleşmiş sonuç üzerinde çalışan testler yakalar; birleştirme kuyruğu yazısı buna bir örnekle bakıyor.
Paralel ajanlar çakışmayı neden artırır?
Her biri kendi git worktree’sinde çalışan birkaç ajan, çalışırken birbirinin dosyalarını ezmez. Ama bu çakışmayı ortadan kaldırmaz, birleştirme anına erteler. Her ajan başladığı tabandan çalışır ve diğerlerinin ne değiştirdiğini görmez. Bazı dosyalar çakışmayı tekrar tekrar çeker:
- her özelliğin bir satır eklediği route tabloları, dependency injection kurulumları ve benzeri kayıt dosyaları,
- barrel dosyaları (
index.ts) ve paylaşılan tipler, package.jsonve lockfile’ı,- çeviri dosyaları, changelog’lar ve config dosyaları.
Ajanların titizliği de burada zarar verir: sadece dokunacakları bir dosyayı baştan formatlar, “hazır elim değmişken” bir yardımcı fonksiyonun adını değiştirir ya da alakasız bir lint uyarısını düzeltirler. Bunların her biri iki dalın birlikte değiştirdiği alanı genişletir.
1. adım: dur ve önce bak
Bir merge ya da rebase durduğunda, insan ya da ajan kimseden düzeltmesini istemeden önce nerede olduğunu öğren:
git status # hangi işlem, hangi dosyalar "both modified"
git diff --name-only --diff-filter=U # yalnızca birleştirilemeyen dosyalar
--diff-filter=U birleştirilemeyen yolları seçer; böylece ajana verebileceğin temiz bir liste elde edersin. Çıkış yollarını da unutma. Çakışma beklediğinden büyükse henüz hiçbir şey kaybolmadı:
git merge --abort # merge öncesi duruma dön
git rebase --abort # dalın rebase öncesi hâline dön
Git belgeleri git merge çalıştırmadan önce kendi değişikliklerini commit etmeni ya da stash’lemeni öneriyor, çünkü --abort commit edilmemiş işi her zaman geri kuramaz. Aynısı ajanın worktree’si için de geçerli: içine bir şey birleştirmeden önce ajan işini commit etsin.
2. adım: tabanı görmek için zdiff3’e geç
Git varsayılan olarak yalnızca iki tarafı gösterir:
<<<<<<< HEAD
const timeout = config.timeout ?? 30_000;
=======
const timeout = getTimeout(config);
>>>>>>> feature/retry
Buradan özgün satırın ne olduğunu, dolayısıyla her tarafın ne amaçladığını anlayamazsın. Çakışma stilini zdiff3 yap (Git 2.35’te geldi; daha eski sürümlerde diff3 kullan):
git config --global merge.conflictStyle zdiff3
Artık çakışma, ||||||| işaretinden sonra ortak atayı da içerir:
<<<<<<< HEAD
const timeout = config.timeout ?? 30_000;
||||||| base
const timeout = config.timeout;
=======
const timeout = getTimeout(config);
>>>>>>> feature/retry
Şimdi okunuyor: bir taraf varsayılan değer eklemiş, diğeri okumayı bir fonksiyona taşımış. Doğru çözüm büyük ihtimalle ikisini de tutmak, örneğin varsayılanı getTimeout’un içine koymak. git-config belgelerine göre zdiff3, diff3 gibidir ama çakışmanın başındaki ve sonundaki eşleşen satırları çakışma bölgesinin dışına taşır; parçalar küçük kalır.
Zaten süren bir merge’de, tek bir dosyanın işaretlerini yeni stille yeniden oluşturabilirsin:
git checkout --conflict=zdiff3 src/http/client.ts
Bu, ajan için senin içinden de önemli. Taban olmadan model hangi tarafın neyi değiştirdiğini tahmin etmek zorunda kalır; sessiz veri kaybı da tam o tahminde başlar.
3. adım: ajana ihtiyacı olan bağlamı ver
Çakışma işaretleri satırları gösterir. Ajanın ayrıca her tarafın bu satırları neden değiştirdiğini bilmesi gerekir. Git, bir dosya için iki tarafın geçmişini gösterebilir:
git log --merge -p src/http/client.ts # önce HEAD, sonra MERGE_HEAD tarafındaki diff'ler
git show :1:src/http/client.ts # ortak ata
git show :2:src/http/client.ts # HEAD (ours)
git show :3:src/http/client.ts # MERGE_HEAD (theirs)
Buna insan bağlamını ekle: her dalın görev ya da pull request açıklaması. Sonra şuna benzer bir prompt kullan:
feature/retry dalını main'e birleştiriyoruz, işlem yarıda. Şu dosyalarda
çakışma var (merge.conflictStyle zdiff3, taban görünüyor):
<git diff --name-only --diff-filter=U çıktısı>
main'in amacı: <bir iki cümle ya da PR açıklaması>
feature/retry'ın amacı: <bir iki cümle ya da PR açıklaması>
Her çakışan dosya için:
1. ours, base ve theirs bölümlerini oku; her tarafın tabana göre neyi
değiştirdiğini birer satırla söyle.
2. İki amacı da koruyan bir çözüm yaz. Gerçekten çelişiyorlarsa seçim
yapma, dur ve bana sor.
3. Yalnızca çakışan parçaları düzenle. Formatlama, yeniden adlandırma ya da
alakasız düzeltme yok.
4. Testleri geçsin diye testleri değiştirme, anlamadığın kodu silme.
package-lock.json / pnpm-lock.yaml için: yalnızca package.json'u çöz, sonra
lockfile'ı paket yöneticisiyle yeniden üret.
Bitince: hiç çakışma işareti kalmasın, tip kontrolünü ve testleri çalıştır,
her dosya için hangi taraftan neyi tuttuğunu özetle. git add, git commit ya da
git merge --continue çalıştırma.
Son satır son adımı sende tutar. Dosya başına özet de incelemeyi hızlandırır: her satırı sıfırdan okumak yerine her iddiayı diff’le karşılaştırırsın.
4. adım: dosya dosya, net kurallarla çöz
Temiz bir birleştirme ile sessiz bir gerileme arasındaki farkı birkaç kural belirler:
- Toptan
--oursya da--theirsyok.git checkout --ours <yol>dosyanın bir tarafını bütünüyle alır, diğerini atar. Yalnızca bir tarafın kazanması gerektiğini bildiğin dosyalarda kullan; örneğin zaten yeniden üreteceğin bir dosyada. - Rebase’deki yer değiştirmeye dikkat. Git belgeleri,
git rebasevegit pull --rebasesırasında--ours’un üzerine rebase ettiğin dal,--theirs’ün ise yeniden uygulanan kendi işin olduğunu belirtiyor. Ajanlar bunu şaşırtıcı sıklıkta karıştırır; hangi dalın hangisi olduğunu ona adıyla söyle. - Üretilen dosyaları birleştirme, yeniden üret. Lockfile’lar, snapshot’lar ve derleme çıktıları, kaynak dosyalar çözüldükten sonra onları üreten araçtan gelmeli.
- Değiştir/sil bir karar ister. Bir dal, diğerinin değiştirdiği bir dosyayı sildiyse ajan bunu kendi başına geri getirmemeli ya da silmemeli; durumu bildirip sormalı.
- Büyük çakışmayı böl. Tek dosyada onlarca parça varsa ajandan bölüm bölüm çözüp açıklamasını iste ya da geri çekilip birleştirme sırasını yeniden düşün.
5. adım: devam etmeden önce doğrula
Ajanın “çözdüm” demesi bir iddiadır, kanıt değil. Kontrol et:
git diff --check # kalan çakışma işaretlerini (ve boşluk hatalarını) uyarır
git diff # çözümü incele
pnpm typecheck && pnpm test # ya da projenin kendi kontrolü
git diff --check, değişiklikler çakışma işareti içeriyorsa sıfır dışı bir kodla çıkar; her seferinde çalıştırılacak ucuz bir kapı. Yeni Git sürümlerinde git diff AUTO_MERGE, metinsel çakışmaları çözmek için şimdiye kadar yapılan değişiklikleri gösterir; ajanın tam olarak ne yazdığına odaklı bir bakış.
Sonra işlemi kendin bitir:
git add src/http/client.ts
git merge --continue # ya da: git rebase --continue
Körü körüne kabul etme: çözümdeki kırmızı bayraklar
| Kırmızı bayrak | Genelde anlamı |
|---|---|
| Bir tarafın değişikliği tamamen yok | Ajan iki tarafı birleştirmek yerine birini seçmiş |
| Bir test ya da assertion değişmiş | Çözüm davranışı bozmuş, test de ona uydurulmuş |
| Çakışma listesi dışındaki dosyalar değişmiş | Kapsam kayması: ayrıca incelenmesi gereken formatlama ya da “düzeltmeler” |
| Kod iki kez geçiyor | İki taraf olduğu gibi tutulmuş, birleştirilmemiş |
Kod dışı bir dosyada işaret ya da başıboş ======= kalmış | Kimse git diff --check çalıştırmamış |
Bunlardan birini görürsen ajandan o parçayı açıklamasını iste ya da dosyayı elle yeniden yap. Birleşmiş sonucun yapay zeka ile kod incelemesinden geçmesi iyi bir ikinci göz olur, ama testleri çalıştırmanın yerini tutmaz.
Çakışma olasıyken rebase mi, merge mi?
İkisi de çalışır; farklı şekillerde zorlanırlar.
| Merge | Rebase | |
|---|---|---|
| Nerede çözersin | Bir kez, merge commit’inde | Her commit yeniden uygulanırken, tek tek |
| Aynı çakışma iki kez | Hayır | Olabilir, birkaç commit’te |
--ours / --theirs | Senin dalın / diğer dal | Yer değiştirir: hedef / kendi işin |
| Geçmiş | Merge commit’i kalır | Doğrusal, dalın commit’lerini yeniden yazar |
| Paylaşılan dalda güvenli mi | Evet | Yalnızca o dalın üzerine kimse bir şey kurmuyorsa |
Yalnızca senin kullandığın kısa ömürlü ajan dallarında main’e sık rebase etmek çoğu zaman daha kolay bir alışkanlıktır: çakışmalar erken, küçükken çıkar. Uzun ömürlü ya da paylaşılan dallarda merge kullan. Rebase sırasında git rebase --skip o anki commit’i tamamen atar; o commit’e ihtiyaç olmadığından eminsen kullan.
Git hatırlasın: rerere
Aynı dalı tekrar tekrar rebase ediyorsan aynı çakışmayı birden fazla kez çözersin. git rerere (“reuse recorded resolution”) bir çakışmayı nasıl çözdüğünü kaydeder ve aynı çakışma tekrar çıktığında bunu yeniden uygular:
git config --global rerere.enabled true
Açıldıktan sonra git merge ve git commit onu otomatik çalıştırır. İşe yarayan komutlar:
git rerere status # çözümü kaydedilecek yollar
git rerere diff # mevcut çözümün durumu
git rerere remaining # rerere'nin çözemediği çakışmalar
git rerere forget src/http/client.ts # yanlış kaydedilmiş bir çözümü unut
Bilmen gereken iki şey var. rerere index’e dokunmaz; sonucu yine kontrol edip git add yaparsın. Bu iyi bir şey, çünkü yanlış bir çözüm de doğru bir çözüm kadar sadakatle tekrar uygulanır. Eski kayıtları da git rerere gc temizler: varsayılan olarak çözülmemiş kayıtları 15 gün, çözülmüşleri 60 gün sonra.
Birleştirmeden önce çakışmayı kontrol et
Bir birleştirmenin çakışıp çakışmayacağını öğrenmek için onu başlatman gerekmez. Git 2.38’den beri git merge-tree --write-tree birleştirmeyi çalışma ağacına ve index’e dokunmadan yapar:
git merge-tree --write-tree --name-only main feature/retry
echo $? # 0 = temiz, 1 = çakışma var
--name-only ile çakışma bölümü yalnızca dosya adlarını listeler. Git belgeleri boş bir dosya listesine değil çıkış koduna güvenmeyi öneriyor. Bu, ajana hiçbir şeye dokunmadan önce verebileceğin kullanışlı bir adım: “feature/retry main’e temiz birleşiyor mu kontrol et; birleşmiyorsa çakışan dosyaları ve her tarafın ne değiştirdiğini listele.”
Önleme: paralel ajanlarla daha az çakışma
En ucuz çakışma hiç çıkmayandır:
- Küçük görevler. Beş dosya değiştiren bir ajan, elli dosya değiştirenden daha az çakışır. Büyük işleri alana göre böl.
- Her alana tek sahip. Router’ı, şemayı, paylaşılan tipleri hangi ajanın değiştirebileceğine karar ver ve bunu her ajanın talimatına yaz.
- Sık merge ya da rebase. Bir saat yaşayan dal nadiren çakışır; bir hafta yaşayan neredeyse her zaman.
- Yol üstü düzenleme yok. Ajanlara görevlerinin dışında formatlama, yeniden adlandırma ya da düzeltme yapmamalarını söyle.
- Lockfile’a aynı anda tek değişiklik. Bağımlılık eklemeyi tek bir dala bırak ya da her birleştirmeden sonra lockfile’ı yeniden üret.
- Birleştirme kuyruğu. Dallar en güncel uca tek tek iner ve birleşmiş sonuç üzerinde test edilir; anlamsal çakışmalar da yakalanır.
Ajanları ayrı klasörlerde çalıştırmanın kurulum tarafı için Git worktree ile paralel geliştirme ve ajanlar yazısına bak.
AgentVera’da nasıl yapılır?
AgentVera, Claude Code ve Codex gibi kodlama ajanı CLI’larını yan yana çalıştıran, git’i içinde barındıran bir masaüstü uygulaması. Yukarıdaki akışa dokunan özellikler şunlar:
- Worktree’ler ve Git paneli. Her özellik için bir worktree aç ve içinde bir ajan başlat; dosya bazında stage et, commit, fetch, pull ve push yap, diff’leri GitHub tarzı, birleşik ya da yan yana oku.
- Erken uyarılar. AgentVera varsayılan olarak her 5 dakikada bir arka planda
git fetchçalıştırır. Dalına yeni commit’ler geldiğinde bir şerit tek tıkla fast-forward etmeni, iki tarafta da commit varsa rebase etmeni sağlar. Aynı projedeki iki ajan aynı dosyayı düzenlediğinde ajan koordinasyonu seni uyarır; farklı worktree’lerdeki ajanlar içinse birleştirmenin çakışabileceğini not eder. - Dosya sahipliği. Dosya sahipliği ile bir ajana
src/api/**gibi yollar ya da glob’lar verirsin. O ajan çalışırken Claude Code ajanları bu dosyaları düzenlemeden önce durdurulur ve sahibine sormaları söylenir; Codex ve diğer CLI’lar kuralları talimatlarında alır. - Paralel ekip. Paralel ekip (Pro) bir işi her biri kendi worktree’sinde çalışan parçalara böler ve bunları bir entegrasyon dalında birleştirir. Bir birleştirme çakışırsa ya da son kontrol başarısız olursa bir entegrasyon ajanı devreye girer.
- Birleştirme kuyruğu. Birleştirme kuyruğu (Pro) dalları en güncel hedefin üzerine tek tek birleştirir. Çakışmaları bir Claude ajanı çözer, kontrol birleşmiş sonuç üzerinde en fazla 2 düzeltme turuyla çalışır, düzeltilemeyen dal geri gönderilir. Varsayılan olarak dalın inmesi senin onayını bekler.
Tek başına, aynı anda tek dalda çalışıyorsan zdiff3 ve rerere ile düz git yeter. Bu araçlar, birkaç ajan aynı anda dal üretmeye başladığında karşılığını verir.
Sık yapılan hatalar
- Tabanı görmeden çözmek. Varsayılan çakışma stili kodun önceki hâlini gizler;
zdiff3’ü aç. - Prompt olarak yalnızca “çakışmaları düzelt”. Her dalın amacını bilmeyen ajan daha eksiksiz görünen tarafı seçer.
git addve--continue’yu ajana bırakmak. Son adımıgit diff --checkve testlerden sonraya sakla.- Lockfile’ı elle birleştirmek. Manifest’i çöz, sonra yeniden üret.
- Paylaşılan bir dalı rebase etmek. Onun üzerine iş kuran herkes, yeniden yazılmış commit’leri çözmek zorunda kalır.
Sonuç
Yapay zeka ile merge conflict çözmek, ajan resmin tamamını gördüğünde ve kanıt sende kaldığında işe yarar: tabanı gösteren zdiff3 işaretleri, iki amacı da söyleyen ve kestirme yolları yasaklayan bir prompt, git add öncesi git diff --check ve test paketi, tekrar eden çakışmalar için de rerere. Gerisini önleme halleder: küçük görevler, net dosya sahipliği ve tek tek inen dallar.
Kendi ajanlarınla denemek için AgentVera’yı indir.