Hizmete özel teklifTalebinizi bırakın, aynı gün dönelim; en geç 1 iş günü içinde yazılı teklifiniz hazırAynı gün dönüş · 1 iş gününde teklifTeklif alın
Yazılım

Git Merge Conflict Nasıl Çözülür? Çakışmayı Adım Adım Giderme

Talha Aslan 15 dakikalık okuma 3 görüntülenme

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

Git merge conflict, iki dalın aynı dosyada aynı satırları farklı biçimde değiştirmesi yüzünden Git'in kendi başına karar verememesidir. Çözmek için git status ile çakışan dosyaları bulun, her dosyada işaretleri silip doğru içeriği bırakın, git add yapın ve birleştirmeyi tamamlayın. Vazgeçmek isterseniz abort komutu işlemi geri alır.

Panik yapmayın. Yani çakışma, Git'in bozulduğu anlamına gelmez. Git size "burada bir insan kararı gerekiyor" diyor. Dosyalarınız çoğu durumda güvende, çünkü hiçbir şey commit edilmeden önce geri dönmek mümkün.

Bu yazıda sahada gördüğümüz teşhis sırasını izliyoruz. En sık yaşanan durumdan başlıyor, ardından nadir görülen senaryolara geçiyoruz. Komutlar kısa, ayrıca her adımın nedenini yazdık.

Hızlı çözüm: çakışmayı 7 adımda nasıl giderirsiniz?

Bu yüzden sakin bir sıra izleyin. Aşağıdaki liste merge, pull ve rebase için ortaktır. Rebase tarafındaki küçük farkı ilerleyen bölümde anlatıyoruz.

  1. git status yazın ve "Unmerged paths" altında listelenen dosyaları not edin.
  2. Ardından listedeki ilk dosyayı editörde açın ve çakışma işaretlerini arayın.
  3. Her çakışma bloğunda hangi içeriğin kalacağına karar verin. Örneğin bazen bir taraf, bazen ikisinin karışımı doğrudur.
  4. İşaret satırlarını tamamen silin. Dosyada yalnızca nihai kod kalmalı.
  5. Dosyayı kaydedin, ardından git add dosya-adi ile "bu dosya tamam" diye işaretleyin.
  6. Tüm dosyalar bitince testleri ya da derlemeyi çalıştırın. Çünkü çakışma çözmek, çalışan kod demek değildir.
  7. Merge için git commit ya da git merge --continue, rebase için git rebase --continue yazın.

Takıldığınız her an git status yazın. Böylece çıktı genellikle bir sonraki adımı sizin yerinize söyler.

Git merge conflict neden olur?

Çakışma, Git'in iki değişikliği otomatik birleştirememesiyle başlar. Çünkü Git satır satır çalışır. İki kişi farklı dosyaları ya da aynı dosyanın uzak bölgelerini değiştirirse sorun çıkmaz. Ancak aynı satırları değiştirirlerse Git hangisinin doğru olduğunu bilemez.

En sık nedenler şunlardır:

  • İki geliştirici aynı fonksiyonu ya da yapılandırma satırını değiştirdi.
  • Uzun süre yaşayan bir dal, ana daldan çok uzaklaştı.
  • Biri dosyayı sildi ya da yeniden adlandırdı, diğeri o dosyayı düzenledi.
  • Otomatik biçimlendirici tüm dosyanın girintisini değiştirdi.
  • git stash pop, git cherry-pick ya da git revert gibi komutlar eski değişiklikleri üzerine uyguladı.

Örneğin iki kişi aynı fiyat sabitini farklı değerlere çekebilir. Git ikisini de koruyamaz, çünkü tek bir satır var ve iki aday var. Bu yüzden durur ve size sorar.

Önemli bir nokta: çakışma bir hata değil, normal bir iş akışı olayıdır. Ayrıca takım büyüdükçe daha sık görürsünüz. Asıl hedef, çakışmayı sıfırlamak değil, küçük ve kolay tutmaktır.

Çakışma işaretleri ne anlama gelir?

Git, çakışan bölgeyi dosyanın içine yazar. Gördüğünüz üç işaret satırı ise şu işi yapar. Aşağıdaki blok kavramsal bir örnektir:

<<<<<<< HEAD
fiyat = 100
=======
fiyat = 120
>>>>>>> ozellik-dali

Ayraçların anlamı şöyledir:

  • İlk işaret satırından ======= satırına kadar olan kısım, şu an bulunduğunuz dalın (HEAD) içeriğidir.
  • ======= ile son işaret satırı arasındaki kısım, içeri almaya çalıştığınız dalın içeriğidir.
  • Son işaret satırında dalın ya da commit'in adı yazar. Böylece içeriğin nereden geldiğini anlarsınız.

Ancak bu üç satır dosyanın parçası değildir. Bırakırsanız kod derleme aşamasında hata verir. Daha kötüsü, işaretler üretime kadar ulaşabilir. Bu yüzden işaretleri mutlaka silin.

Daha fazla bağlam isterseniz git config merge.conflictStyle diff3 ayarını açın. Bu durumda ortak atanın içeriğini de görürsünüz. Böylece "iki taraf neyi değiştirdi" sorusunu daha rahat yanıtlarsınız. Ayrıntı için Git merge belgesine bakabilirsiniz.

Hangi dosyalarda çakışma var, nasıl görürsünüz?

Önce kapsamı görün, çünkü işin boyutunu bilmek planı kolaylaştırır. Elinizdeki iş küçük mü büyük mü, bilmek moralinizi korur. git status çıktısı iki bölüm gösterir: otomatik birleşenler ve "Unmerged paths" altındaki çakışanlar.

Yalnızca çakışan dosyaların adını görmek için şu komut işe yarar:

git diff --name-only --diff-filter=U

Durum satırlarının anlamı da önemlidir:

  • "both modified": iki taraf da dosyayı değiştirdi. En yaygın durum budur.
  • "deleted by us" ya da "deleted by them": bir taraf dosyayı sildi, diğeri düzenledi.
  • "both added": iki taraf aynı adla farklı dosya ekledi.

Öte yandan silme çakışmasında işaret satırı görmezsiniz. Karar basittir ama bilinçli olmalı: dosyayı tutacak mısınız, silecek misiniz? Tutmak için git add, silmek için git rm kullanırsınız.

Çalışma ağacınızda başka bekleyen değişiklikler varsa onları not alın. Böylece bu not, vazgeçme kararında işinize yarar. Aksi halde abort sonrası neyin size ait olduğunu karıştırabilirsiniz.

Dosyada doğru içeriği nasıl seçersiniz?

Her çakışma bloğunda üç seçenek vardır: kendi tarafınızı tutmak, karşı tarafı tutmak ya da ikisini birleştirmek. Ancak doğru seçim kod okumayı gerektirir. Bu adımı otomatiğe bağlamayın.

Sahada şu soruları sırayla soruyoruz. Çünkü doğru cevap çoğu zaman kodda değil, amaçta saklı:

  • Bu iki değişiklik aynı amaca mı hizmet ediyor, yoksa iki ayrı ihtiyacı mı karşılıyor?
  • Hangi taraf daha yeni bir ihtiyaca cevap veriyor?
  • Her ikisi de gerekliyse sıralama ya da isimlendirme çakışması yaratır mı?
  • Yazarla konuşmak gerekiyor mu?

Üstelik son soru en çok atlanan sorudur. Örneğin karşı tarafın neden o satırı değiştirdiğini bilmiyorsanız, tahmin etmeyin. Commit mesajına bakın: git log --merge -p dosya-adi çakışmaya katkı veren commit'leri gösterir.

Örnek senaryo: bir geliştirici fonksiyonun adını değiştirdi, diğeri aynı fonksiyona yeni koşul ekledi. Doğru sonuç ikisini birleştirir: yeni ad ve yeni koşul birlikte kalır. Yalnız bir tarafı seçmek ise burada sessizce özellik kaybettirir.

Çözümü git add ve commit ile nasıl bitirirsiniz?

Dosyayı düzenleyip kaydettikten sonra Git'e "bu dosya tamam" demeniz gerekir. Bunu da git add yapar. Komut dosyayı hazırlık alanına alır ve çakışma durumunu temizler.

Tüm dosyalar için aynı işlemi yaptıktan sonra git status tekrar çalıştırın. "All conflicts fixed" benzeri bir mesaj görürseniz sona yaklaşmışsınız demektir. Ardından:

git add dosya-adi
git commit
# ya da: git merge --continue

Commit mesajı genellikle hazır gelir. Ayrıca mesajın içinde çakışan dosyaların listesi bulunabilir. İsterseniz bu mesajı koruyun, isterseniz çözümün nedenini bir cümleyle ekleyin. Ekibin ileride "bu satırı neden böyle bıraktık" diye sormasına gerek kalmaz.

Burada bir tuzak var. git add . yazmak kolaydır ama işareti hâlâ içinde duran bir dosyayı da hazırlık alanına alır. Önce git diff --check çalıştırın. Komut, geride unuttuğunuz işaret satırlarını uyarı olarak gösterir. Böylece hatalı bir commit'i baştan engellersiniz.

Rebase sırasında git merge conflict nasıl çözülür?

Rebase, commit'lerinizi tek tek yeni bir tabanın üzerine yeniden uygular. Bu yüzden her adımı ayrı düşünmek gerekir. Bu nedenle çakışma her commit için ayrı ayrı çıkabilir. Mantık aynıdır: dosyayı çözün, git add yapın. Fark, son adımda commit yazmamanızdır.

Rebase'de doğru komut şudur:

git add dosya-adi
git rebase --continue

Bu komut bir sonraki commit'e geçer. Yani yeni bir çakışma çıkarsa süreç tekrar eder. Son commit de uygulanınca rebase biter. Bir commit'in içeriği tamamen gereksiz hale geldiyse git rebase --skip o commit'i atlar. Bunu yalnızca ne yaptığınızdan eminseniz kullanın.

Ayrıca rebase sırasında "ours" ve "theirs" kavramları yer değiştirir. Çünkü Git, kendi commit'lerinizi başka bir dalın üstüne tek tek taşır. Bu yüzden "ours" taban dalını, "theirs" ise taşınan sizin commit'lerinizi gösterir. Ayrıntı için Git rebase belgesi bu konuyu açıklıyor.

Çok sayıda çakışma bekliyorsanız rebase yerine tek bir merge daha az sürpriz yaratabilir. Aşağıdaki karşılaştırma tablosu bu farkı özetliyor.

Vazgeçmek isterseniz merge ve rebase işlemini nasıl iptal edersiniz?

Çözüm yarıda karıştıysa ise geri dönebilirsiniz. Commit atılmadan önce işlem tamamen iptal edilebilir. Doğru komut işleme göre değişir:

  • Merge için git merge --abort yazın. Git, birleştirme öncesi duruma dönmeye çalışır.
  • Rebase için git rebase --abort yazın. Dal, rebase başlamadan önceki haline döner.
  • Cherry-pick için git cherry-pick --abort kullanırsınız.

Bir uyarı önemli: merge başlamadan önce commit etmediğiniz değişiklikleriniz varsa abort onları her zaman geri getiremeyebilir. Nitekim Git belgeleri bunu açıkça söyler. Bu yüzden merge öncesi çalışma ağacınızı temiz tutun ya da değişiklikleri commit edin ya da stash'leyin.

Abort sonrası dalınız eski haline döner ama çakışma sorunu ortadan kalkmaz. Aynı birleştirmeyi tekrar denerseniz aynı çakışmayı yeniden görürsünüz. Önce ana dalı kendi dalınıza çekmek, çakışmayı yavaş yavaş çözmek daha rahat olabilir.

Editörün birleştirme aracı çakışmada nasıl yardım eder?

Metin editöründe işaretleri elle silmek yerine görsel bir araç da kullanabilirsiniz. Örneğin çoğu modern editör çakışan blokları renklendirir. Mevcut değişikliği, gelen değişikliği ya da ikisini birden kabul etmeniz için tıklanabilir seçenekler sunar.

Visual Studio Code bunlardan biridir. Ayrıntılar için VS Code kaynak denetimi belgesine bakın. Eklentiler ve ayarlar için VS Code ve Visual Studio karşılaştırma yazımız işinize yarar.

Git'in kendi aracı da vardır: git mergetool. Seçtiğiniz bir harici birleştirme programını açar. Tercih ettiğiniz aracı merge.tool ayarıyla tanımlarsınız. Araç çoğu zaman .orig uzantılı yedek dosyalar bırakır. Bunları commit etmemeye dikkat edin.

Görsel araçların bir riski var: tek tıkla "bu tarafı kabul et" demek çok kolaydır. Ancak kolaylık dikkatsizliğe dönüşebilir. Her çakışmayı kabul etmeden önce iki tarafı da okuyun. Ayrıca sonuçta testleri çalıştırmayı unutmayın.

--ours ve --theirs ile bir tarafı tümüyle seçmek güvenli mi?

Bazen ise bir dosyada yalnızca bir taraf doğrudur. Örneğin kaynaktan yeniden üreteceğiniz bir derleme çıktısı bu gruba girer. Bu durumda tek komutla bir tarafı seçebilirsiniz:

git checkout --ours -- dosya-adi
git checkout --theirs -- dosya-adi

İlki mevcut dalınızın, ikincisi gelen dalın sürümünü getirir. Sonrasında git add yapmayı unutmayın. Merge'de "ours" sizin dalınız, rebase'de ise tam tersidir.

Risk şudur: dosyanın tamamını seçtiğinizde karşı tarafın o dosyadaki tüm değişikliği, çakışmayan kısımlar dahil, kaybolur. Yani bir satırlık çakışma yüzünden yüzlerce satırlık iş silinebilir. Bu yüzden bu yolu yalnızca bilinçli olarak, tek dosya için kullanın.

Benzer isimli iki farklı kavramı da sık karıştırırız:

  • git merge -X ours: yalnızca çakışan parçalarda sizin tarafınızı tutar, çakışmayan değişiklikler yine birleşir.
  • git merge -s ours: karşı dalın tüm değişikliğini yok sayar, ama geçmişte birleşmiş gibi kaydeder.

İkincisi çok güçlüdür ve çoğu zaman istenmeyen bir sonuçtur. Emin değilseniz kullanmayın.

package-lock gibi kilit dosyalarındaki çakışmayı nasıl çözersiniz?

Kilit dosyalarını (package-lock.json, yarn.lock gibi) araçlar üretir. Bu yüzden satırlarını elle birleştirmek hataya açıktır. Çünkü bağımlılık ağacı birbirine bağlıdır ve bir satırı yanlış seçerseniz tutarsız bir ağaç elde edersiniz.

Genel yaklaşım şudur:

  1. Önce package.json dosyasındaki çakışmayı insan gözüyle çözün. İki taraf hangi paketleri istiyor, karar verin.
  2. Kilit dosyası için taraflardan birinin sürümünü alın, örneğin git checkout --theirs -- package-lock.json.
  3. Ardından npm install çalıştırın. Araç kilit dosyasını güncel package.json ile uyumlu hale getirir.
  4. Yeni kilit dosyasını git add ile işaretleyin ve testleri çalıştırın.

Detaylar için npm package-lock belgesi iyi bir kaynaktır. Kilit dosyasını çözerken ağaç hatası alırsanız npm ERESOLVE hatası yazımıza bakın.

Önemli kural: kilit dosyasını silip sıfırdan üretmek son çaredir. Ekibinizin tüm sürümlerini kaydıran bir sonuç doğurabilir.

İkili dosyalarda git merge conflict nasıl çözülür?

Görsel, PDF, tasarım dosyası ya da sıkıştırılmış paket gibi ikili dosyaları Git satır satır birleştiremez. Bu nedenle Git bu dosyalarda çakışma işareti yazmaz. Sadece "iki taraf değiştirdi" der ve sizden birini seçmenizi bekler.

Çözüm basittir ama dikkat ister:

  1. Hangi sürümün doğru olduğunu belirleyin. Gerekirse dosyayı iki sürüm halinde açıp elle karşılaştırın.
  2. Doğru tarafı git checkout --ours -- dosya ya da --theirs ile getirin.
  3. Dosyayı git add ile işaretleyin.

Eğer iki taraf da farklı ve gerekli değişiklikler yaptıysa Git bunu birleştiremez. O durumda değişiklikleri ilgili araçta (örneğin tasarım programında) elle birleştirmeniz gerekir. Bu yüzden ikili dosyalar için ekip içinde sahiplik kuralı koymak çok işe yarar: aynı anda tek kişi düzenler.

Ayrıca büyük ikili dosyaların depoda tutulması başka sorunlar da yaratır. Mümkünse bunlar için ayrı bir depolama düzeni düşünün.

Merge ve rebase çakışmaları arasında hangi farklar var?

İki yöntem de aynı işaretleri üretir, ancak çakışma sayısı değişir. Fark, çakışmanın ne zaman ve kaç kez çıktığındadır. Aşağıdaki tablo özet verir.

ÖlçütMergeRebase
Çakışma sayısıGenellikle tek seferde, tüm dal içinHer commit için ayrı ayrı çıkabilir
Çözüm sonrası komutgit commit ya da git merge --continuegit rebase --continue
Vazgeçmegit merge --abortgit rebase --abort
"ours" anlamıBulunduğunuz dalTaban dal, yani sizin üzerine taşındığınız dal
"theirs" anlamıGetirdiğiniz dalTaşınan sizin commit'leriniz
Geçmişe etkisiBirleştirme commit'i eklerCommit'leri yeniden yazar
Paylaşılan dalda riskDüşükYüksek, geçmiş değişir

Kısacası, paylaşılan dallarda merge daha öngörülebilirdir. Kendi özel dalınızda ise rebase daha temiz bir geçmiş bırakır. Hangisini seçeceğinize ekip kuralı karar vermeli.

Çözdükten sonra doğru çözdüğünüzü nasıl doğrularsınız?

Çakışmayı çözmek ile doğru çözmek farklı şeylerdir. Çünkü Git dosyayı birleşmiş saydığında bile mantık hataları kalabilir. Bu yüzden commit öncesi kısa bir doğrulama rutini kurun.

  • git diff --check ile unuttuğunuz işaretleri arayın.
  • Projeyi derleyin ya da başlatın. Sözdizimi hatası çakışmadan kalmış olabilir.
  • Ayrıca mevcut testleri çalıştırın. Özellikle çakışan dosyalara dokunan testlere bakın.
  • git diff --staged ile commit'e girecek son halin gözden geçirin.
  • Mümkünse karşı tarafın yazarına kısa bir bakış attırın.

Hata ayıklama alışkanlığı burada işe yarar. Sorun çıkarsa hata ayıklama teknikleri yazımızdaki yöntemlerle küçük adımlarla ilerleyin.

Tamamlanmış bir birleştirmeyi geri almak istiyorsanız commit'ten sonra da seçenekleriniz var. Ancak paylaştığınız bir geçmişte bunu yaparken ekibe haber verin.

Çakışma belirtileri ve çözümleri tek bakışta nasıl görünür?

Çakışmanın türünü ilk bakışta tanımak zaman kazandırır. Aşağıdaki tablo, sahada en sık gördüğümüz durumları nedenleri ve çözümleriyle eşleştirir. Sıralama en olasıdan en az olasıya doğrudur.

BelirtiOlası nedenÇözüm
Dosyada işaret satırları var, durum "both modified"İki taraf aynı satırı değiştirdiDoğru içeriği seçin, işaretleri silin, git add yapın
Durum "deleted by us" ya da "deleted by them"Biri sildi, diğeri düzenlediDosyayı tutmaya git add, silmeye git rm ile karar verin
Durum "both added"Aynı adla iki farklı dosya eklendiİçerikleri karşılaştırın, birini yeniden adlandırın
Kilit dosyasında çok sayıda işaretBağımlılıklar iki dalda farklı güncellendipackage.json'ı çözün, kilit dosyasını araçla yeniden üretin
İkili dosyada "iki taraf değiştirdi" uyarısıGörsel ya da paket iki dalda değiştiDoğru sürümü ours ya da theirs ile alın
Rebase her commit'te durduÇok sayıda commit aynı alanı değiştirdiTek tek çözün, ya da merge ile tek seferde birleştirin

Bu tablo bir başlangıç noktasıdır. Elbette her proje kendi özel durumunu getirir. Yine de önce işareti okumak, sonra türünü belirlemek, en son komutu seçmek doğru sıradır.

Çakışmayı çözerken hangi küçük alışkanlıklar işinizi kolaylaştırır?

Teknik komutlar kadar çalışma düzeni de önemlidir. Aşağıdaki alışkanlıklar hem hızı hem güveni artırır. Üstelik hiçbiri ek araç gerektirmez.

  • Çözmeye başlamadan önce bir yedek dal açın: git branch yedek-dal komutu mevcut noktayı korur. Yani işler kötüye giderse dönecek yeriniz olur.
  • Bir dosyayı bitirince hemen git add yapın. Böylece hangi dosyanın hazır olduğunu unutmazsınız.
  • Dosyaları sırayla çözün. Aynı anda üç dosyayı açık tutmak hata ihtimalini artırır.
  • Anlamadığınız bir satırı geçmeyin. Önce commit mesajını okuyun, gerekirse yazara sorun.
  • Çözüm bitince farkı bir kez daha okuyun. Çünkü gözden kaçan işaret ya da yanlış taraf burada yakalanır.

Bu adımlar yavaş görünür, ancak toplamda zaman kazandırır. Hatalı bir çakışma çözümü, günler sonra beklenmedik bir hata olarak geri döner. O zaman nedenini bulmak çok daha pahalıdır.

Çakışmaları baştan nasıl azaltırsınız?

Çakışmayı sıfırlamak mümkün değil. Ama sıklığını ve boyutunu azaltmak mümkün. Sahada işe yarayan alışkanlıklar şunlardır:

  • Küçük ve sık birleştirin. Yani haftalarca yaşayan dal, çakışma birikimidir.
  • Dalınızı düzenli olarak ana dalla güncelleyin. Böylece çakışmayı küçükken çözersiniz.
  • Küçük commit'ler atın. Bir commit tek bir amaca hizmet etsin.
  • Ayrıca biçimlendirme değişikliklerini ayrı commit'e alın. Böylece anlam değişikliği ile girinti gürültüsü karışmaz.
  • Kod sahipliği tanımlayın. Hangi modülün kimde olduğu belli olsun.
  • Aynı dosyada aynı anda çalışacaksanız önceden haberleşin.

Ayrıca git rerere özelliğini düşünebilirsiniz. Aynı çakışmayı tekrar tekrar çözüyorsanız (uzun yaşayan dallarda sık olur), Git önceki çözümünüzü hatırlayıp uygulayabilir. Bunu rerere.enabled ayarıyla açarsınız.

Git komutlarına yeni başlıyorsanız Git ve GitHub temel komutlar rehberimiz güzel bir başlangıçtır. Ekip içi iş birliği kuralları için GitHub katkı rehberimize de göz atın.

GitHub'da çakışma çıkarsa web arayüzünde mi, yerelde mi çözmelisiniz?

Pull request açtığınızda GitHub çakışmayı otomatik algılar. Basit çakışmalar için web düzenleyicisi yeterli olabilir. GitHub Docs, hangi durumlarda bunun mümkün olduğunu ve hangilerinde komut satırı gerektiğini anlatır. Ayrıntı için GitHub Docs çakışma çözme sayfasına bakın.

Genel kural şu: küçük, tek dosyalık ve anlaşılır çakışmalarda web arayüzü hızlıdır. Birden fazla dosya, silme ya da yeniden adlandırma içeren durumlarda yerel çalışma daha güvenlidir. Çünkü yerelde testi çalıştırabilir, geçmişi inceleyebilirsiniz.

Bir nokta daha var. Web arayüzünde çözdüğünüz kod, siz bilgisayarınızda test etmeden dala girer. Eğer proje kritikse yerelde çözmeyi tercih edin.

Ekip olarak hangi hatalar çakışmayı büyütür?

Teknik bilgi kadar alışkanlıklar da önemlidir. Sahada gördüğümüz yaygın hatalar şunlardır:

  • Çakışma işaretlerini silmeyi unutup commit atmak.
  • Tek taraflı seçimle ("hep benimki") karşı tarafın işini silmek.
  • Çözümü test etmeden dala göndermek.
  • Paylaşılan dalda, haber vermeden rebase yapıp geçmişi değiştirmek.
  • Büyük özelliği haftalarca tek dalda tutmak.
  • Otomatik biçimlendiriciyi tüm projede bir anda çalıştırmak.

Bunların çoğu süreç sorunudur, araç sorunu değildir. Kısa ömürlü dallar, açık sahiplik ve zorunlu test adımı çözümün büyük kısmını oluşturur.

Örnek senaryo: üç kişilik bir ekip, ayın sonunda tüm dalları aynı gün birleştiriyor. Her ay yoğun bir çakışma günü yaşıyorlar. Birleştirmeyi haftalık yapmaya başlayınca çakışmalar küçülür ve haftaya yayılır. Bu bir ölçüm değil, kavramsal bir örnektir.

git pull sırasında git merge conflict nasıl çözülür?

git pull aslında iki işi birleştirir: önce uzak değişiklikleri indirir, sonra bulunduğunuz dala birleştirir. Yani pull sırasındaki çakışma, sıradan bir merge çakışmasıdır. Bu yüzden aynı adımlarla ilerlersiniz.

Ayarınıza göre pull, merge yerine rebase de yapabilir. Çıktıdaki ifadelere bakın. "rebase in progress" görüyorsanız çözümden sonra git rebase --continue yazmanız gerekir. Aksi halde yanlış komutla süreci karıştırırsınız.

Pull'u denerken "local changes would be overwritten" benzeri bir uyarı alıyorsanız bu başka bir durumdur. O zaman Git daha çakışma aşamasına bile gelmeden durmuştur. Önce değişikliklerinizi commit edin ya da geçici olarak stash'leyin, sonra tekrar deneyin.

Bir de güvenli alışkanlık var. Önemli bir pull öncesinde git fetch ile değişiklikleri indirin ve git log ile neyin geldiğine bakın. Böylece çakışmayı önceden tahmin edersiniz.

Stash, cherry-pick ve revert çakışmaları nasıl farklıdır?

Çakışma yalnızca merge ve rebase ile sınırlı değil. Geçmişten değişiklik taşıyan her komut çakışma üretebilir. İşaretler aynıdır. Farklı olan, işlemi nasıl bitireceğinizdir.

  • Stash: git stash pop çakışırsa Git kayıtlı stash'i silmez. Çözümü bitirdikten sonra stash'i kendiniz temizlersiniz.
  • Cherry-pick: Çözümden sonra git cherry-pick --continue yazarsınız, vazgeçmek için --abort kullanırsınız.
  • Revert: Aynı mantıkla git revert --continue ve --abort çalışır.

Ayrıca git status çıktısı çoğu zaman hangi işlemin yarım kaldığını ve sonraki komutu açıkça söyler. Bu yüzden komutu ezberlemek yerine çıktıyı okumak daha güvenlidir.

Örnek senaryo: bir hata düzeltmesini yayın dalına cherry-pick ile taşıdınız. Yayın dalında o dosya farklı olduğu için çakışma çıktı. Doğru yaklaşım, düzeltmenin amacını koruyup yayın dalının mevcut kodunu bozmamaktır.

Çakışma sırasında dosyanın üç sürümünü nasıl görürsünüz?

Git çakışmada aslında üç sürümü saklar: ortak atanın sürümü, sizin sürümünüz ve karşı tarafın sürümü. Dosyada gördüğünüz işaretler bunların karışımıdır. Bazen karışım okunmaz hale gelir.

O durumda her sürüme ayrı ayrı bakın. git show :1:dosya-adi ortak atayı, :2: sizin tarafınızı, :3: karşı tarafı gösterir. Bu sözdizimi Git belgelerinde dizin aşamaları olarak geçer. Yani üç sürümü yan yana okuyabilirsiniz.

Böylece "ilk hâl neydi, kim neyi değiştirdi" sorusunu net yanıtlarsınız. Özellikle büyük dosyalarda ve uzun fonksiyonlarda bu yaklaşım sizi zaman kaybından kurtarır.

Sonuca ulaşamıyorsanız çakışmayı bırakıp git merge --abort yapın. Önce dalınızı güncelleyin, sonra küçük parçalar halinde yeniden birleştirin.

Çözüm yetmezse ne zaman destek almalısınız?

Çoğu çakışmayı bu yazıdaki adımlarla çözersiniz. Ama bazı durumlar daha derin analiz ister. Örneğin kritik bir üretim dalında çakışma varsa ya da geçmiş karışmışsa dikkatli ilerlemek gerekir.

Önce işi durdurun ve mevcut durumu not alın. git status çıktısını ve hangi komutu çalıştırdığınızı kaydedin. Gerekirse yedek bir dal oluşturun. Sonra karar verin.

Depo yapınız, dallanma stratejiniz ya da dağıtım süreciniz sürekli çakışma üretiyorsa sorun kodda değil süreçtedir. Bu durumda ekip düzenine ve yazılım altyapısına birlikte bakmak gerekir. Özel yazılım geliştirme hizmetimiz kapsamında bu tür iş akışı sorunlarını da ele alıyoruz. İhtiyacınıza uygun teklif almak için hizmet sayfasından bize ulaşabilirsiniz.

SSH erişimi ya da bağımlılık sorunları gibi komşu hatalarla uğraşıyorsanız SSH publickey hatası yazımıza bakın.

Sıkça Sorulan Sorular

Git merge conflict nedir?
Git merge conflict, Git'in iki dalın değişikliğini otomatik birleştirememesidir. İki taraf aynı satırları farklı biçimde değiştirdiğinde ya da biri dosyayı silip diğeri düzenlediğinde oluşur. Bu bir hata değildir. Git, kararı sizin vermenizi ister ve dosyaya çakışma işaretleri yazar. Siz seçtikten sonra birleştirme tamamlanır.
Git merge conflict çözerken verileri kaybeder miyim?
Doğru ilerlerseniz kaybetmezsiniz. Commit atılmadan önce git merge --abort ya da git rebase --abort ile işlemi geri alabilirsiniz. Risk, bir tarafı tümüyle seçtiğinizde karşı tarafın değişikliklerini bilmeden silmenizdir. Birleştirme öncesi commit edilmemiş değişiklikleriniz varsa abort onları geri getirmeyebilir, bu yüzden önce commit ya da stash yapın.
Merge sırasında vazgeçmek için hangi komutu kullanırım?
Merge için git merge --abort, rebase için git rebase --abort yazarsınız. Her ikisi de dalınızı işlem başlamadan önceki duruma getirmeye çalışır. Cherry-pick için git cherry-pick --abort vardır. Komutlar yalnızca işlem yarım kaldığında çalışır. Commit tamamlandıysa geri alma yöntemi farklıdır.
Rebase sırasında ours ve theirs neden ters görünür?
Rebase, sizin commit'lerinizi başka bir dalın üstüne tek tek yeniden uygular. Bu yüzden Git için ours taban dalı, theirs ise taşınan sizin commit'leriniz olur. Merge'deki anlamın tersidir. Bir tarafı toptan seçmeden önce bu farkı git rebase belgesinden kontrol edin, yoksa yanlış tarafı tutarsınız.
package-lock.json çakışmasını elle düzenleyebilir miyim?
Elle düzenlemek önerilmez, çünkü kilit dosyası bağımlılık ağacını makine için kaydeder. Önce package.json çakışmasını çözün, kilit dosyası için bir tarafı alın, ardından npm install ile dosyayı yeniden uyumlu hale getirin. Sonuçta testleri çalıştırın. Ağaç hatası alırsanız ilgili npm belgesine bakın.
Git merge conflict çıkmasını nasıl azaltırım?
Küçük ve sık birleştirme yapın, dalınızı ana dalla düzenli güncelleyin ve commit'leri tek amaçlı tutun. Biçimlendirme değişikliklerini ayrı commit'e alın, kod sahipliğini netleştirin. Aynı çakışmayı sık çözüyorsanız git rerere ile Git'in önceki çözümü hatırlamasını sağlayabilirsiniz. Çakışma tamamen bitmez ama küçülür.
  • git merge conflict
  • git çakışma çözme
  • git rebase
  • git status
  • package-lock çakışması
  • merge ve rebase farkı
  • git merge abort
Paylaş:
Talha Aslan

Google Partner dijital pazarlama uzmanı. 2012’den beri SEO, Google Ads, web tasarım ve e-ticaret projelerinde sahada; bu blogda gördüğünüz her yazı o deneyimden çıkar.

Sıradaki proje

Projeniz için teklif alın.

Talebiniz doğrudan Talha Aslan ve ekibine ulaşır: stratejiyi Talha kurar, uygulamayı deneyimli ekip yürütür. Aynı gün dönüş yapar, kapsamı, takvimi ve tutarı yazılı teklifle 1 iş günü içinde göndeririz.