ENBirlikte üretelim
← Argo Ajans

Kurumsal Yazılım

Git merge conflict nasıl çözülür? Adım adım çakışma çözme rehberi

Mehmet Said Göksu ·

Git merge conflict nasıl çözülür? Adım adım çakışma çözme rehberi

Kısa yanıt

Git merge conflict, iki dal aynı dosyanın aynı satırını farklı şekilde değiştirdiğinde oluşur. Çözüm için git status ile çakışan dosyaları bulun, <<<<<<</=======/>>>>>>> işaretleri arasından doğru satırları seçin, işaretleri silin, git add ile işaretleyin ve git commit ile birleştirmeyi tamamlayın. Emin olmadığınız çakışmalarda commit öncesi testleri çalıştırın.

Bu adımlar her editörde ve her işletim sisteminde aynı mantıkla çalışır; farklılık yalnızca merge conflict’i görsel olarak gösteren araçtadır.

Merge conflict nedir ve neden oluşur?

Bir ekip aynı proje üzerinde paralel dallarda (branch) çalıştığında, Git çoğu değişikliği otomatik olarak birleştirir. Ancak iki dal aynı dosyanın aynı satırını birbirinden farklı biçimde değiştirmişse, ya da bir dal bir dosyayı silerken diğer dal o dosyayı düzenlemişse, Git hangi değişikliğin doğru olduğuna karar veremez. Bu durumda birleştirme işlemi yarıda durur ve bir merge conflict ortaya çıkar.

Bu, bir hata değil, Git’in bilinçli bir güvenlik önlemidir. Git’in resmî kitabına göre Git, birleştirme sonucunun belirsiz olmadığı durumları akıllıca tespit eder; ama belirsizlik varsa otomatik ve “akıllı” bir tahmin yapmaya çalışmaz, kararı insana bırakır. Yani her merge conflict aslında Git’in “burada yanlış bir tahmin yapmak yerine sana soruyorum” demesidir.

Çakışmanın en sık görüldüğü senaryolar şunlardır:

  • İki geliştiricinin aynı fonksiyonu veya aynı yapılandırma dosyasını eş zamanlı düzenlemesi
  • Uzun süre ana daldan (main/master) ayrı kalan bir özellik dalının, ana dal çok değiştikten sonra birleştirilmeye çalışılması
  • Bir dosyanın bir dalda silinip diğer dalda hâlâ düzenlenmesi
  • Otomatik biçimlendirme araçlarının (formatter) aynı dosyayı farklı dallarda farklı şekilde yeniden biçimlendirmesi

git status ile çakışan dosyaları bulma

Bir git merge veya git pull komutu bir merge conflict ile sonuçlandığında terminalde şu satırı görürsünüz:

Auto-merging src/app.js
CONFLICT (content): Merge conflict in src/app.js
Automatic merge failed; fix conflicts and then commit the result.

Hangi dosyaların çakıştığını tek tek terminaldeki mesajlardan takip etmek yerine git status komutunu çalıştırmak daha güvenilirdir:

$ git status
On branch feature/odeme-formu
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   src/app.js
        both modified:   src/config.json

both modified etiketi, o dosyada bir merge conflict olduğunu ve iki tarafın da değişiklik yaptığını gösterir. Büyük bir birleştirmede onlarca dosya çakışabilir; bu yüzden çözmeye başlamadan önce git status çıktısındaki tam listeyi görmek, hiçbir merge conflict’i atlamamanın ilk adımıdır.

Çakışma işaretlerini okuma

Git, çakışan her dosyanın içine kendi özel işaretlerini ekler. Örneğin aynı satırı değiştiren iki dal birleştirilmeye çalışıldığında dosya şöyle görünür:

<<<<<<< HEAD
const KDV_ORANI = 0.20;
=======
const KDV_ORANI = 0.18;
>>>>>>> feature/vergi-guncelleme

Bu bloğu üç parçaya ayırarak okuyun:

  • <<<<<<< HEAD ile ======= arasındaki kısım, şu an üzerinde bulunduğunuz dalın (genellikle sizin son değişikliğinizin) hâlidir.
  • ======= ile >>>>>>> dal-adı arasındaki kısım, birleştirmeye çalıştığınız diğer dalın hâlidir.
  • >>>>>>> dal-adı satırındaki isim, çakışan değişikliğin hangi daldan geldiğini gösterir; bu bilgi kimle konuşmanız gerektiğini bulmak için işe yarar.

Çözüm, bu üç işareti (<<<<<<<, =======, >>>>>>>) dosyadan tamamen silip yalnızca doğru olan satırları bırakmaktır. Bazen doğru cevap iki tarafı da tutmak, bazen ikisini birleştirmek, bazen ikisini de atıp üçüncü bir değeri yazmaktır — Git burada bir öneri sunmaz, kararı içeriğe bakan kişi verir.

Git merge conflict nasıl çözülür? Adım adım

Bir merge conflict çözme süreci, kullandığınız araçtan bağımsız olarak aynı beş adımdan oluşur: dosyayı bulun, işaretleri okuyun, doğru içeriğe karar verin, işaretleri temizleyin, sonucu commit edin.

Komut satırında çözüm

  1. git status ile hangi dosyaların çakıştığını listeleyin.
  2. Her çakışan dosyayı bir metin editöründe açın ve <<<<<<</=======/>>>>>>> bloklarını tek tek gözden geçirin.
  3. Hangi satırların kalacağına karar verin, işaretleri silin.
  4. Dosyayı çözülmüş olarak işaretlemek için git add çalıştırın:
git add src/app.js
git add src/config.json
  1. Tüm çakışan dosyalar git add ile işaretlendikten sonra birleştirmeyi tamamlayın:
git commit

Git bu commit için genellikle otomatik bir mesaj önerir (“Merge branch ‘feature/vergi-guncelleme’”); bu mesaj çoğu durumda değiştirilmeden bırakılabilir. Eğer süreç sırasında çakışmanın karmaşıklaştığını, yanlış bir dalı birleştirdiğinizi ya da baştan başlamak istediğinizi fark ederseniz git merge --abort komutu, henüz commit atılmadığı sürece birleştirmeyi iptal edip dalı merge öncesindeki temiz hâline döndürür.

VS Code veya başka bir editörde çözüm

Görsel bir merge conflict aracı, aynı beş adımı daha okunur hâle getirir. VS Code gibi editörler çakışan dosyayı açtığında “Current Change”, “Incoming Change” ve “Accept Both Changes” gibi tıklanabilir kısayollar gösterir; bu kısayollar arka planda yine aynı işaretleri kaldırıp doğru satırları bırakır. Karmaşık, birden fazla bloklu çakışmalarda görsel araç hata riskini azaltır, ama küçük ve tek satırlık çakışmalarda komut satırı genelde daha hızlıdır. Hangi araç kullanılırsa kullanılsın, dosyada <<<<<<< veya >>>>>>> işareti kalmadığından emin olmadan git add çalıştırmak, bu işaretlerin yanlışlıkla koda karışmasına yol açar — bu, sık görülen ve fark edilmesi geciken bir hatadır.

Kilit dosyalarda ve binary dosyalarda merge conflict

package-lock.json, yarn.lock veya composer.lock gibi otomatik üretilen kilit dosyaları da sık sık merge conflict üretir; bu tür dosyalarda satır satır elle çözmeye çalışmak yerine kilit dosyasını silip ilgili paket yöneticisinin kurulum komutunu (npm install, yarn install gibi) yeniden çalıştırmak genelde daha güvenilirdir, çünkü sonuç bağımlılık ağacıyla tutarlı kalır. Görsel, video veya derlenmiş paket gibi binary dosyalarda ise Git metin içindeki gibi satır satır bir işaret koyamaz; iki sürümden hangisinin kalacağına karar vermek ve git checkout --ours <dosya> ya da git checkout --theirs <dosya> komutuyla doğru sürümü seçip git add ile işaretlemek gerekir.

GitHub’da pull request içinde merge conflict çözme

Bir pull request “This branch has conflicts that must be resolved” uyarısı gösterdiğinde iki yol vardır. Merge conflict tek bir dosyada, ikili olmayan (metin tabanlı) ve nispeten basitse, GitHub’ın kendi web arayüzündeki çakışma düzenleyicisi kullanılabilir: bu araç aynı <<<<<<</=======/>>>>>>> işaretlerini tarayıcıda gösterir ve düzenlemeyi doğrudan platform üzerinden commit’e çevirir. GitHub’ın resmî dokümantasyonu bu iki yöntemi de adım adım anlatır.

Merge conflict birden fazla dosyada, büyük bir binary dosyada (görsel, tasarım dosyası, derlenmiş paket) ya da yapı olarak karmaşıksa, tarayıcıdan çözmeye çalışmak riskli olur; bu durumda dalı yerel makineye çekip komut satırında çözmek, sonucu test edip öyle push etmek daha güvenlidir. Bir merge conflict’i yalnızca “kırmızıyı kaldır, yeşili bırak” mantığıyla, kodu çalıştırmadan çözmek, çakışmayı ortadan kaldırsa da çalışan bir sonuç garanti etmez — bu yüzden karmaşık çakışmalarda çözümden sonra mutlaka test çalıştırılmalıdır.

Rebase sırasındaki merge conflict’ler merge’den nasıl farklıdır?

git rebase kullanıldığında da aynı çakışma işaretleri ve aynı çözüm mantığı geçerlidir, ama süreç farklı ilerler. Merge işleminde tek bir birleştirme anı vardır ve tek bir commit ile biter. Rebase işleminde ise dalınızdaki her commit sırayla, tek tek yeniden uygulanır; aynı satırdaki bir değişiklik birden fazla commit’te tekrar ediyorsa, aynı çakışma birden fazla kez, her seferinde ayrı bir commit için çıkabilir. Her çakışmayı çözdükten sonra git add ile işaretleyip git rebase --continue komutuyla bir sonraki commit’e geçilir; süreç yarıda bırakılmak istenirse git rebase --abort dalı rebase öncesindeki hâline döndürür.

Bir ekip için pratik kural şudur: paylaşılan, başkalarının da üzerinde çalıştığı bir dalda rebase yapmak geçmişi değiştirdiği için ek risk taşır; bu riskin ne zaman kabul edilebilir olduğu, ekibin sürüm kontrol ve dağıtım sürecinin bir parçasıdır. DevOps rehberimizde anlattığımız küçük ve sık teslim ilkesi burada da geçerlidir: dallar ne kadar uzun süre ana daldan ayrı kalırsa, birleştirme anındaki çakışma sayısı ve karmaşıklığı da o kadar artar.

Merge conflict’leri önlemenin yolları

Her merge conflict’i sıfıra indirmek mümkün değildir, ama sıklığını ve boyutunu azaltmak mümkündür:

  • Dalları kısa tutun. Bir özellik dalı ne kadar uzun süre ana daldan ayrı kalırsa, geri dönüşte o kadar fazla değişiklik birikir ve merge conflict riski artar.
  • Ana daldan sık sık güncelleme alın. Kendi dalınıza düzenli olarak git pull veya git merge main ile ana daldaki değişiklikleri işleyin; birikmiş büyük bir farkla tek seferde uğraşmak yerine küçük ve sık çakışmalarla karşılaşırsınız.
  • Dosyaları küçük ve odaklı tutun. Tek bir dosyada çok fazla sorumluluk birikirse, birden fazla kişinin o dosyaya aynı anda dokunma olasılığı artar.
  • Ekip içinde iletişim kurun. Aynı dosya veya aynı modül üzerinde eş zamanlı çalışıldığını bilmek, çakışmayı önlemez ama kimin ne değiştirdiğini anlamayı kolaylaştırır.
  • Otomatik biçimlendirme kurallarını tek bir yapılandırmada sabitleyin. Farklı geliştiricilerin farklı formatter ayarlarıyla aynı dosyayı yeniden biçimlendirmesi, içerik değişmese bile satır satır çakışma üretir.

Sık yapılan hatalar

  • İşaretleri okumadan git add çalıştırmak. Dosyada hâlâ <<<<<<< veya >>>>>>> kalmışsa bu satırlar sessizce koda karışır ve fark edilmesi günler alabilir.
  • Panikle her şeyi tek bir taraftan seçmek. “Kendi değişikliğimi” ya da “gelen değişikliği” düşünmeden seçmek, merge conflict’i çözer ama diğer tarafın mantıklı bir sebebi olan değişikliğini sessizce siler.
  • Testleri atlamak. Çakışma metinsel olarak çözülse bile, sonucun gerçekten çalıştığından emin olmak için ilgili testleri veya en azından uygulamayı yerelde çalıştırmak gerekir.
  • git merge --abort’u geç fark etmek. Commit atıldıktan sonra bu komut işe yaramaz; geri dönmek isteniyorsa commit öncesinde karar verilmelidir.
  • Büyük ve seyrek birleştirmeleri alışkanlık hâline getirmek. Aynı sorun tekrar tekrar yaşanıyorsa, asıl düzeltilmesi gereken şey tek tek merge conflict’ler değil, dalların ne kadar uzun süre ayrı kaldığıdır.

Kontrol listesi

Bir merge conflict ile karşılaştığınızda sırasıyla şunları kontrol edin:

  • git status çalıştırıp çakışan dosyaların tam listesini gördünüz mü?
  • Her dosyadaki <<<<<<</=======/>>>>>>> bloklarının tamamını tek tek okudunuz mu?
  • Karar verirken sadece “hangisi benim” değil, “hangisi doğru” sorusunu sordunuz mu?
  • İşaretleri sildikten sonra dosyada başka bir <<<<<<< veya >>>>>>> kalmadığını kontrol ettiniz mi?
  • git add ile işaretledikten sonra ilgili testleri veya uygulamayı çalıştırdınız mı?
  • Commit mesajı, neyin neden birleştirildiğini anlaşılır kılıyor mu?

Sonraki adım

Git merge conflict, ekip büyüdükçe ve dallar çoğaldıkça kaçınılmaz hâle gelen ama doğru sırayla ilerlendiğinde her zaman çözülebilir bir durumdur. Sorunu büyüten şey genelde merge conflict’in kendisi değil, panikle atılan aceleci bir karardır. git status ile dosyayı bulmak, işaretleri satır satır okumak ve sonucu test etmeden commit etmemek, çoğu vakayı güvenle kapatır. Dal stratejisi ve sürüm akışını kurumsal bir çerçevede planlamak isterseniz kurumsal web tasarım süreçleri rehberimize bakabilirsiniz.

Ekibinizin sürüm kontrol akışını, dal stratejisini veya dağıtım sürecini baştan kurmak isterseniz kurumsal yazılım çözümlerimize göz atabilir ya da doğrudan bizimle iletişime geçebilirsiniz. Grup şirketimiz Web Tasarım Ofisi, web projelerinde sürüm kontrolü dahil teknik altyapı ve sürdürülebilir bakım konusunda destek veriyor.

İlgili rehberler

Sıkça sorulan sorular

Git merge conflict nedir?

Merge conflict, iki farklı dal (branch) aynı dosyanın aynı satırını farklı biçimde değiştirdiğinde ya da bir dal bir dosyayı silerken diğeri aynı dosyayı düzenlediğinde ortaya çıkar. Git iki değişiklikten hangisinin doğru olduğuna kendi başına karar veremez ve birleştirme işlemini durdurup kullanıcıdan karar vermesini bekler.

Merge conflict ile rebase conflict arasındaki fark nedir?

Merge sırasında Git iki dalı birleştirmeye çalışırken çakışırsa tek bir çakışma anıyla karşılaşırsınız. Rebase sırasında ise her commit sırayla yeniden uygulanır; bu yüzden aynı satırdaki değişiklik birden fazla commit'te tekrar ederse çakışma birden fazla kez, her commit için ayrı ayrı çıkabilir.

Çakışma işaretlerini (<<<<<<<, =======, >>>>>>>) nasıl okumalıyım?

<<<<<<< HEAD ile ======= arasındaki bölüm sizin şu an bulunduğunuz dalın (genellikle kendi çalışmanızın) hâlidir. ======= ile >>>>>>> arasındaki bölüm ise birleştirilmek istenen dalın hâlidir. Hangi satırların kalacağına karar verip bu üç işareti de dosyadan tamamen silmeniz gerekir.

git merge --abort ne zaman kullanılır?

Çakışmalar karmaşıklaştığında veya yanlış bir birleştirmeye başladığınızı fark ettiğinizde git merge --abort komutu birleştirme işlemini iptal eder ve dalı merge öncesindeki temiz hâline döndürür. Bu komut yalnızca commit henüz tamamlanmadan, çakışma çözme aşamasındayken çalışır.

GitHub'da pull request içindeki bir merge conflict nasıl çözülür?

Çakışma basit, metin tabanlı ve tek bir dosyada ise GitHub'ın web arayüzündeki çakışma düzenleyicisi kullanılabilir. Çakışma birden fazla dosyada, ikili (binary) bir dosyada veya karmaşık yapıdaysa yerel makinede komut satırıyla çözüp değişikliği push etmek daha güvenlidir.

Bu konuda yardım mı lazım?

Özel Yazılım

Hizmeti inceleyinHemen iletişime geçin
İyi işler, iyi bir konuşmayla başlar.

Birlikte
iz bırakalım.

İzmir ofis
Tariş Cd. (1497. Sok.) No. 5C Ofis P22
35230 Alsancak, İzmir, Türkiye
Birleşik Krallık ofis
167 Sheen Lane
SW14 8NA London, United Kingdom
Kayseri ofis
Sahabiye Mh. Buyurkan Sok. No.29
38015 Kocasinan, Kayseri, Türkiye
Projenizi bize anlatın