aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Araçlar & DevOps

Git Merge Conflict Çözümü: Adım Adım Rehber

Bir git merge conflict ekrana düştüğünde çoğu geliştiricinin ilk tepkisi panik olur, oysa çakışma aslında Git'in sana yardım etme biçimidir. Git, iki farklı dalda aynı satırların farklı şekilde değiştirildiğini fark eder ve hangisinin doğru olduğuna karar veremez; bu yüzden işi durdurup kararı sana bırakır. Bu rehberde çakışmanın neden oluştuğunu, terminalde işaretleri nasıl okuyacağını ve dosyayı güvenle nasıl temizleyeceğini adım adım göreceksin.

Merge conflict tam olarak nedir?

Git değişiklikleri satır satır birleştirir. İki dal aynı dosyanın farklı bölgelerine dokunduğunda Git ikisini de sorunsuz harmanlar. Çakışma yalnızca aynı satırlar (veya birbirine çok yakın satırlar) iki dalda farklı şekilde değiştirildiğinde ya da bir tarafta silinip diğerinde düzenlendiğinde ortaya çıkar. Bu durumda Git "burada iki olası gerçek var, hangisini istiyorsun?" diye sorar.

Çakışma şu komutların hemen hepsinde görülebilir: git merge, git rebase, git pull (içinde merge veya rebase çalıştırır), git cherry-pick ve git stash pop. Mekanizma hepsinde aynıdır, dolayısıyla bir kez çözmeyi öğrenince hepsi için geçerli olur.

Çakışmayı okumak: işaretler ne anlatır?

Çakışan bir dosyayı açtığında Git'in eklediği üç işaret görürsün:

<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 10000;
>>>>>>> feature/login
  • <<<<<<< HEAD ile ======= arası: senin tarafın (üzerinde bulunduğun dal, "ours").
  • ======= ile >>>>>>> arası: gelen taraf, yani birleştirdiğin dal ("theirs").
  • Sondaki etiket (feature/login) çakışan değişikliğin nereden geldiğini söyler.

Önemli bir ayrıntı: rebase sırasında "ours" ve "theirs" anlamı terstir, çünkü rebase senin commit'lerini hedef dalın üzerine yeniden oynatır. Yani HEAD hedef dalı, alt blok ise senin değişikliğini gösterir. Komutla çözüyorsan bunu aklında tut.

Adım adım çözüm

İşte güvenli ve tekrarlanabilir bir akış:

  1. Durumu gör. git status çalıştır; "Unmerged paths" başlığı altında çakışan dosyaları listeler.
  2. Çakışan dosyaları aç. Her işaret bloğunu bul. Üç seçeneğin var: senin tarafını tut, gelen tarafı tut ya da ikisini elle harmanla.
  3. Doğru sonucu yaz. Üç işaret satırını (<<<<<<<, =======, >>>>>>>) mutlaka sil ve geriye yalnızca istediğin nihai kod kalsın.
  4. Çözüldü olarak işaretle. git add <dosya> ile dosyayı sahneye al.
  5. İşlemi tamamla. Merge'de git commit, rebase'de git rebase --continue, cherry-pick'te git cherry-pick --continue ile devam et.

Editör desteği işi çok kolaylaştırır. VS Code çakışan blokları renklendirir ve "Accept Current Change / Accept Incoming Change / Accept Both Changes" düğmelerini gösterir. Yine de düğmeye basmadan önce sonucun mantıklı olduğunu kendin kontrol et; otomatik kabul her zaman doğru kodu vermez.

Komut satırından hızlı kararlar

Bazen bir dosyada baştan sona tek bir tarafı istediğini bilirsin. O zaman dosyayı elle düzenlemek yerine:

# bu dosyada tamamen benim dalımı tut
git checkout --ours config/app.php
# bu dosyada tamamen gelen dalı tut
git checkout --theirs config/app.php
# sonra sahneye al
git add config/app.php

Çakışmadan önceki noktaya tümüyle dönmek istersen git merge --abort (veya rebase için git rebase --abort) seni başlangıç durumuna geri taşır. Hiçbir şeyi bozmadan baştan başlamanın en temiz yoludur.

Çakışmaları en başta azaltmak

En iyi çakışma, hiç yaşanmayan çakışmadır. Birkaç alışkanlık riski belirgin biçimde düşürür:

  • Sık ve küçük commit'le, sık entegre et. Bir dalı haftalarca ana daldan uzak tutmak çakışma birikimine davetiyedir. git pull --rebase ile düzenli olarak güncel kal.
  • Dosyaları küçük ve odaklı tut. Devasa tek dosyalar yerine modüler yapı, iki kişinin aynı satıra dokunma olasılığını azaltır.
  • Otomatik üretilen dosyalara dikkat et. composer.lock, package-lock.json gibi kilit dosyaları sık çakışır; bunları yeniden üretip (örn. composer install) çözmek elle düzeltmekten güvenlidir.
  • Biçimlendirmeyi standartlaştır. Ekipçe tek bir formatlayıcı (Prettier, PHP-CS-Fixer) kullanmak, yalnızca girinti/boşluk yüzünden çıkan sahte çakışmaları yok eder.

Çözümü doğrulamak

Çakışmayı kapattıktan sonra "derleniyor mu" diye bakmak yetmez. Birleştirdiğin değişikliğin iki tarafının da niyetini koruduğundan emin ol: testleri çalıştır, uygulamayı aç, çakışan bölgenin bağlı olduğu davranışı elle dene. git diff ile commit öncesi son hali bir kez daha gözden geçirmek, yanlışlıkla bırakılmış bir >>>>>>> satırını veya silinmesi gereken eski kodu yakalamanın hızlı yoludur.

Sık Sorulan Sorular

Çakışmayı çözerken yanlış tarafı tuttum, geri alabilir miyim?

Henüz commit etmediysen git merge --abort ile tüm merge'i iptal edip baştan başlayabilirsin. Zaten commit ettiysen git reflog ile önceki HEAD'i bulup git reset --hard <hash> ile o noktaya dönebilirsin; bu yüzden çözümü doğrulamadan push etmemek önemlidir.

Aynı çakışmaları tekrar tekrar çözüyorum, çözüm var mı?

Evet. git config --global rerere.enabled true ile rerere (reuse recorded resolution) özelliğini aç. Git, bir çakışmayı nasıl çözdüğünü hatırlar ve aynısı tekrar çıkarsa otomatik uygular; uzun süren rebase'lerde çok işe yarar.

"ours" ve "theirs" merge ile rebase'de neden farklı?

Merge'de bulunduğun dal "ours"tur. Rebase'de Git önce hedef dalı tabana alıp senin commit'lerini onun üzerine oynattığı için roller terse döner: HEAD hedef dalı temsil eder, "theirs" ise senin oynatılan değişikliğindir. Kararı verirken hangi komutta olduğunu kontrol et.

Çakışmalar projeni yavaşlatıyor mu? Git iş akışını, dallanma stratejisini ve dağıtım sürecini birlikte düzene sokabiliriz. Projen için yardım istersen benimle iletişime geç.

Devamı için