Git'te birleştirme çatışmaları nasıl çözülür

Git'teki birleşme çatışmalarının nasıl çözüleceğini açıklamanın iyi bir yolu var mı?

4274
02 окт. Spoike 02 ekim ayarladı . 2008-10-02 14:31 '08, 02:31, 2008-10-02 14:31
@ 37 cevaplar
  • 1
  • 2

Deneyin: git mergetool

Her çatışmanın içinden geçen grafik arayüzü açar ve nasıl birleştirileceğini seçebilirsiniz. Bazen bu daha sonra küçük bir manuel düzenleme gerektirir, ancak genellikle kendi başına yeterlidir. Bu her şeyi elle yapmaktan çok daha iyidir.

@JoshGlover yorumuna göre:

Yüklemezseniz, komutun GUI'yi açması gerekmez. git mergetool için git mergetool çalıştırmak git mergetool kullanımına yol açtı. Bunun yerine kullanmak için aşağıdaki araçlardan birini kurabilirsiniz: meld , opendiff , kdiff3 , tkdiff , gvimdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , vimdiff , vimdiff , emerge .

Aşağıda birleştirme çakışmalarını çözmek için vimdiff kullanma prosedürünün bir örneği verilmiştir. Bu bağlantı ile

Adım 1 : Terminalinizde aşağıdaki komutları çalıştırın

 git config merge.tool vimdiff git config merge.conflictstyle diff3 git config mergetool.prompt false 

Bu vimdiff'u varsayılan birleştirme aracı olarak ayarlayacaktır.

Adım 2 : Aşağıdaki komutu terminalde çalıştırın

 git mergetool 

Adım 3 : Aşağıdaki formatta bir ekran görüntüsü göreceksiniz.

  +----------------------+ | | | | |LOCAL |BASE |REMOTE | | | | | +----------------------+ | MERGED | | | +----------------------+ 

Bu 4 türleri

YEREL, geçerli daldaki dosyadır.

BASE - Ortak bir ata, dosyanın her iki değişiklikten önce nasıl göründüğü

UZAKTAN - şubenize birleştirdiğiniz bir dosya

MERGED - Birleşmenin sonucu, depoda depolanan budur

ctrl+w kullanarak bu görünümler arasında gezinebilirsiniz ctrl+w ve j ctrl+w kullanarak doğrudan MERGED görünümüne gidebilirsiniz.

Burada ve burada vimdiff navigasyon hakkında daha fazla bilgi .

Adım 4 MERGED'i aşağıdaki gibi düzenleyebilirsiniz.

UZAKTAN değişiklik almak istiyorsanız

 :diffg RE 

BASE'ten değişiklik almak istiyorsanız

 :diffg BA 

LOCAL’dan değişiklikler almak istiyorsanız

 :diffg LO 

Adım 5 Kaydet, çık, kilitle ve temizle

:wqa kaydet ve :wqa çık

git commit -m "message"

git clean diff aracı tarafından oluşturulan gereksiz dosyaları silin (örneğin, * .orig).

2535
02 окт. Cevap Peter Burns 02 ekim tarafından verildi . 2008-10-02 20:50 '08, 08:50, 2008-10-02 20:50

İşte yukarıdan muhtemel bir emsal:

Bazı değişiklikler yapacaksınız, ancak ne yazık ki, bilmiyorsunuz:

 git fetch origin git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Updating a030c3a..ee25213 error: Entry 'filename.c' not uptodate. Cannot merge. 

Böylece, güncelleme yaparsınız ve tekrar deneyin, ancak bir çelişki var:

 git add filename.c git commit -m "made some wild and crazy changes" git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Auto-merging filename.c CONFLICT (content): Merge conflict in filename.c Automatic merge failed; fix conflicts and then commit the result. 

Yani değişikliklere göz atmaya karar verdin:

border=0
 git mergetool 

Oh, ben, oh, benim, yukarı akım bazı şeyleri değiştirdi, ama sadece değişikliklerimı kullanmak için ... hayır ... onların değişiklikleri ...

 git checkout --ours filename.c git checkout --theirs filename.c git add filename.c git commit -m "using theirs" 

Ve sonra son kez deneriz.

 git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Already up-to-date. 

Sürpriz!

1625
04 авг. Cevap CoolAJ86 04 ağustos tarafından verilmiştir . 2010-08-04 20:04 '10, 20: 04'de 2010-08-04 20:04

Birleştirme araçlarının nadiren çatışmayı veya çözümü anlamama yardımcı olduğunu buluyorum. Genellikle bir metin düzenleyicisindeki çakışma belirteçlerine daha fazla bakarım ve git günlüğünü ek olarak kullanırım.

İşte bazı ipuçları:

1. konsey

Bulduğum en iyi birleştirme çatışmasının diff3 stilini kullanmak:

git config merge.conflictstyle diff3

Bu gibi çatışma belirteçleri yaratır:

 <<<<<<< Changes made on the branch that is being merged into. In most cases, this is the branch that I have currently checked out (ie HEAD). ||||||| The common ancestor version. ======= Changes made on the branch that is being merged in. This is often a feature/topic branch. >>>>>>> 

Orta kısım ortak ataların nasıl göründüğüdür. Bu kullanışlıdır, çünkü her bir dalda neyin değiştiğini daha iyi anlamak için, her bir değişikliğin amacının ne olduğu hakkında daha iyi bir fikir vermek için bunu alt ve üst sürümlerle karşılaştırabilirsiniz.

Çatışma sadece birkaç satırdan oluşuyorsa, bu kural olarak çatışmayı çok belirgin kılar. (Bir çatışmayı nasıl çözeceğinizi bilmek çok farklıdır: başkalarının üzerinde ne üzerinde çalıştığını bilmeniz gerekir. Kafanız karışıksa, aradığınızı görmeleri için bu kişiyi odanızda aramanız en iyisidir.)

Eğer çatışma daha uzunsa, üç bölümün her birini “benim”, “ortak” ve “onlar” gibi üç ayrı dosyaya kesip yapıştırıyorum.

Sonra, çatışmaya neden olan iki durumu görmek için aşağıdaki komutları çalıştırabilirim:

 diff common mine diff common theirs 

Birleştirme aracı, çakışan olmayan tümsek parçalarını içereceğinden, birleştirme aracını kullanmakla aynı değildir. Dikkatini dağıtıcı buluyorum.

İki ipucu

Birisi bundan daha önce bahsetti, ancak her kelimenin farkının arkasındaki amacı anlamak, çatışmanın nereden geldiğini ve bununla nasıl başa çıkacağını anlamak için genellikle yararlıdır.

 git log --merge -p <name of file> 

Bu, ortak bir ata ile birleştirdiğiniz iki kafa arasındaki bu dosyayı ilgilendiren tüm taahhütleri gösterir. (Bu nedenle, birleşmeden önce her iki dalda zaten var olan taahhütleri içermez.) Bu, mevcut çatışmanızdaki bir etmen olmayan farkları görmezden gelmenize yardımcı olur.

Üç ipucu

Değişikliklerinizi otomatik araçlarla kontrol edin.

Otomatik testleriniz varsa, bunları çalıştırın. Tüysüzse , koş. Bir inşaat projesiyse, tamamlamadan önce inşa edilmesi gerekir. Her durumda, değişikliklerin bozulmadığından emin olmak için küçük bir test yapmanız gerekir. (Heck, çakışma olmadan birleştirmek bile çalışma kodunu bozabilir.)

Dördüncü ipucu

Önceden planlayın; meslektaşları ile iletişim kurmak.

Önceden planlama yapılması ve başkalarının çalıştığının farkına varılması, birleşme çatışmalarının önlenmesine ve / veya daha önce çözülmelerine yardımcı olabilir;

Örneğin, siz ve başka bir kişinin aynı dosya kümesini etkileyecek farklı yeniden yapılandırmalar üzerinde çalıştığını biliyorsanız, birbirinizle önceden iyi konuşmalı ve her birinizin ne tür değişiklikler yaptığını daha iyi anlamalısınız. Paralel olarak değil, planlanan değişiklikleri sırayla gerçekleştirirseniz çok zaman ve emek tasarrufu yapabilirsiniz.

Büyük bir kod parçasını geçen büyük yeniden düzenlemeler için, sıralı olarak çalışmayı ciddi şekilde düşünmelisiniz: herkes bu kod alanında çalışmayı durdurur ve bir kişi tam bir yeniden düzenleme gerçekleştirir.

Tutarlı bir şekilde çalışamıyorsanız (belki de geçici baskı yüzünden), o zaman beklenen birleşme çatışmalarından bahsetmek, en azından sorunları daha önce çözmenize yardımcı olur, ancak ayrıntılar hala taze. Örneğin, bir çalışan bir hafta içinde yıkıcı bir dizi işlem yaparsa, bu şubeyi bu hafta günde bir veya iki kez birleştirmek / yeniden paketlemek isteyebilirsiniz. Bu şekilde, birleştirme / yeniden yönlendirme çakışmalarını bulursanız, her şeyi bir araya getirmek için birkaç hafta beklemekten büyük bir parçaya ayırmaktan daha hızlı bir şekilde çözebilirsiniz.

Beşinci ipucu

Birleşmeden emin değilseniz, zorlamayın.

Özellikle bir çok çakışan dosya olduğunda ve çakışma belirteçleri yüzlerce çizgiyi kapsıyorsa, birleştirme zor olabilir. Genellikle, yazılım projelerini değerlendirirken, çılgın bir birleşme işlemesi gibi ek ücretler için yeterli zaman eklemiyoruz, bu nedenle her çatışmayı analiz etmek için birkaç saat harcamak için gerçek bir direnç gibi geliyor.

Uzun vadede, önceden planlama yapmak ve başkalarının çalıştığını anlamak, birleşme çatışmalarını tahmin etmek ve daha kısa sürede doğru çözümü hazırlamak için en iyi araçlardır.

696
29 сент. Cevap Mark E. Haase tarafından verilmiştir 29 Eylül. 2011-09-29 00:08 '11 0:08 2011-09-29 00:08
  • Hangi dosyaların çakışmadığını belirleyin (Git bunu size söylemelidir).

  • Her dosyayı açın ve farkları öğrenin; Git onları sınırlandırıyor. Her bloğun hangi versiyonunun tutulacağı belli olur umarım. Bunu, kodu tamamlayan diğer geliştiricilerle tartışmanız gerekebilir.

  • git add the_file dosyasındaki çakışmayı çözdükten sonra git add the_file dosyasını git add the_file .

  • Tüm çatışmaları çözer çözmez git rebase --continue komutunu veya bitince Git'in söylediği herhangi bir komutu çalıştırın.

326
02 окт. cevabı davetron5000 02 ekim. 2008-10-02 15:41 '08, 15:41, 2008-10-02 15:41

Abort Git İptal Etme sorusundaki cevapları, özellikle de bir sorun dosyasının çeşitli sürümlerini nasıl görüntüleyeceğini gösteren Charles Bailey'in Yanıtını kontrol edin.

100
03 окт. Tarafından cevap verilen Pat Notz Ekim 03 2008-10-03 18:15 '08, 18:15, 2008-10-03 18:15

Bir dosyada değişiklikler aynı anda yapıldığında çakışma birleşmesi oluyor. İşte çözmek için nasıl.

git CLI

Bir çatışma durumunda iken atmanız gereken basit adımlar:

  • Çakışan dosyaların listesine dikkat edin: git status ( Unmerged paths bölümünde).
  • Aşağıdaki yaklaşımlardan biriyle her dosya için çakışmaları ayrı ayrı çözün:

    • Çakışmaları çözmek için GUI'yi kullanın: git mergetool (en kolay yol).

    • Uzak / başka bir sürümü kabul etmek için, şunu kullanın: git checkout --theirs path/file . Bu, bu dosyada yaptığınız yerel değişiklikleri reddeder.

    • Yerel / git checkout --ours path/file kabul etmek için şunu kullanın: git checkout --ours path/file

      Ancak, dikkatli olmalısınız, çünkü silinen değişiklikler bazı nedenlerle ortadan kaldırılmıştır.

      İlgili: Git'teki "bizim" ve "onlar" ın tam anlamı nedir?

    • Çakışan dosyaları manuel olarak düzenleyin ve kod bloğunu <<<<< / >>>>> arasına yerleştirin, daha sonra yukarıdaki veya altındaki sürümü seçin ===== . Bakınız: Çatışmaların nasıl sunulduğu .

    • Yol ve dosya adı çakışmaları git add / git rm ile çözülebilir.

  • Son olarak, kullanıma hazır dosyaları inceleyin: git status .

    Hala Unmerged paths altında dosyalarınız varsa ve çakışmayı el ile çözdüyseniz, Unmerged paths çözdüğünüzü bilmesini sağlayın: git add path/file .

  • Tüm çatışmalar başarıyla çözüldüyse, değişiklikleri kopyalayın: git commit -a ve silinmiş git commit -a tıklayın.

Ayrıca bakınız: GitHub'daki bir birleştirme çakışmasını komut satırından çözme

DiffMerge

Windows, macOS ve Linux / Unix'teki dosyaları görsel olarak karşılaştırabilen ve birleştirebilen DiffMerge'i başarıyla kullandım.

Grafiksel olarak 3 dosya arasındaki değişiklikleri görüntüler ve otomatik birleştirme (güvenli olduğunda) ve elde edilen dosyanın düzenlenmesi üzerinde tam kontrol sağlar.

2019

05 авг. Cevap kenorb 05 ağustosta verilir . 2015-08-05 17:29 '15, 17:29 2015-08-05 17:29

Sık sık küçük taahhütler yaparsanız, taahhütlü yorumları git log --merge ile görüntüleyerek git log --merge . O zaman git diff size çatışmaları gösterecek.

Birden çok satır içeren çatışmalar için, harici GUI aracında neler olduğunu görmek kolaydır. Opendiff'i seviyorum - Git ayrıca vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff'i destekliyor, kutudan çıkıyor ve başkalarını yükleyebilirsiniz: git config merge.tool "your.tool" seçtiğiniz aracı yükler ve ardından başarısız olduktan sonra git mergetool birleştirme size bağlamda farklılıklar gösterecektir.

Bir çakışmayı çözmek için bir dosyayı her düzenlediğinizde, git add filename dizini günceller ve farkınız artık göstermez. Tüm çatışmalar işlendiğinde ve dosyaları git add eklendiğinde, git commit birleştirmeyi tamamlar.

75
02 окт. cevap Paul 02 ekim verilir . 2008-10-02 19:11 '08, 07:11, 2008-10-02 19:11

Çatışmaların nasıl olduğunu anlamak için bkz. Çatışmaların Nasıl Sunulduğunu veya Git'te, git merge belgelerini git merge .

Ayrıca, Çakışmaların nasıl çözüleceği bölümü, çakışmaların nasıl çözüleceğini açıklar:

Çatışmayı gördükten sonra iki şey yapabilirsiniz:

  • Birleşmemeye karar verin. İhtiyacınız olan tek temizleyici, HEAD ters dönüşüm 2. için sabitlemek ve 2. ve 3. bölümde yapılan çalışma köyü değişikliklerini temizlemek için bir sıfırlama dizin dosyasıdır; git merge --abort bunun için kullanılabilir.

  • Çatışmaları çöz. Git, çalışma ağacındaki çatışmaları işaretler. Formdaki dosyaları düzenleyin ve git add dizinine git add . Bir anlaşma imzalamak için git commit kullanın.

Birkaç araçla çatışma halinde çalışabilirsiniz:

  • Mergetool kullanın. git mergetool bir birleştirme git mergetool için çalışacak bir grafik bir birleştirme aracı çalıştırmak için mergetool.

  • Farklılıklara bak. git diff , hem HEAD hem de MERGE_HEAD değişiklikleri vurgulayan üç taraflı bir git diff gösterir.

  • Her dal arasındaki farklara bakın. git log --merge -p <path> önce HEAD sürümü, ardından MERGE_HEAD sürümü için diff gösterecektir.

  • Orijinallere bak. git show :1:filename ortak atayı gösterir, git show :2:filename HEAD sürümünü gösterir ve git show :3:filename MERGE_HEAD sürümünü gösterir.

Ayrıca birleştirme çatışmasının markası ve bunların Pro Git Ana Birleştirme Anlaşmazlıkları bölümünde nasıl çözüleceğini de okuyabilirsiniz.

43
14 июля '13 в 21:34 2013-07-14 21:34 Cevap user456814 14 Temmuz 13, 21 : 34'te 2013-07-14 21:34

Emacs için, yarı manuel birleştirme çatışmalarını çözmek isteyen kullanıcılar:

 git diff --name-status --diff-filter=U 

Çakışma çözümü gerektiren tüm dosyaları görüntüler.

Bu dosyaların her birini birer birer veya birer birer açın:

 emacs $(git diff --name-only --diff-filter=U) 

Emac’larda düzenleme gerektiren bir arabellek ziyaret ederken,

 ALT+x vc-resolve-conflicts 

Bu üç tamponu (benim, onlar ve çıktı tamponu) açacaktır. "N" (sonraki alan), "p" (tahmin alanı) düğmesine basarak gezinin. Alanımı veya alanınızı sırasıyla çıktı arabelleğine kopyalamak için "a" ve "b" tuşlarına basın. Ve / veya çıktı tamponunu doğrudan düzenleyin.

Bittiğinde: "q" ye basın. Emacs bu tamponu saklamak isteyip istemediğinizi sorar: evet. Tampon tamamlandığında, tekerleğin açılışında çözüldüğü şekilde işaretleyin:

 git add FILENAME 

Her tür tamponla çalışmayı bitirme

 git commit 

birleştirme işlemini tamamlamak için

36
23 февр. cevap 23 eci verilmiştir. 2013-02-23 02:04 '13, 02:04 2013-02-23 02:04

Sürümümü veya sürümlerini tamamen istiyorum veya bireysel değişiklikleri görmek ve her biri için bir karar vermek istiyorum.

Sürümümü tamamen kabul et :

Sürümümü kabul et (yerel, bizim):

 git checkout --ours -- <filename> git add <filename> # Marks conflict as resolved git commit -m "merged bla bla" # An "empty" commit 

Sürümlerini kabul et (silinmiş):

 git checkout --theirs -- <filename> git add <filename> git commit -m "merged bla bla" 

Çakışan tüm dosyalar için yapmak istiyorsanız , şunu çalıştırın:

 git merge --strategy-option ours 

veya

 git merge --strategy-option theirs 

Tüm değişiklikleri inceleyin ve ayrı ayrı kabul edin.

  1. git mergetool
  2. Değişiklikleri gözden geçirin ve her biri için herhangi bir sürümü kabul edin.
  3. git add <filename>
  4. git commit -m "merged bla bla"

Varsayılan olarak, mergetool komut satırında çalışır. Birleştirme aracı komut satırının nasıl kullanılacağı ayrı bir sorun olmalıdır.

Bunun için örneğin meld ve run gibi görsel bir araç da kurabilirsiniz.

 git mergetool -t meld 

Yerel (bizim), "temel" veya "birleştirilmiş" sürüm (birleştirmenin geçerli sonucu) ve uzaktan kumandalar açılacaktır. Birleştirilen sürümü git mergetool -t meld , git mergetool -t meld " 'i dosyaları birleştirmeye gerek yok' 'olana kadar git mergetool -t meld çalıştırın, sonra 3. ve 4. git mergetool -t meld gidin.

28
29 сент. Cevap Noidea 29 Eylül tarafından verilmektedir . 2016-09-29 16:02 '16, 16:02 2016-09-29 16:02

Git'teki birleştirme çakışmalarını düzeltmek için lütfen aşağıdaki adımları tamamlayın:

  1. Git Durumunu Kontrol Et: Git Durumunu Kontrol Et

  2. Yama setini alın: git fetch ( git görevinizden doğru yamayı kontrol edin)

  3. Yerel şubeyi ayıkla (benim örneğimde temp1): git checkout -b temp1

  4. En yeni içeriği master'den çıkart : git pull - rebase origin master

  5. Mergetool çalıştırın, çatışmaları kontrol edin ve düzeltin ... ve uzak şubenizdeki değişiklikleri mevcut şubeniz ile kontrol edin: git mergetool

  6. Durumu tekrar kontrol et: git status

  7. Yerel olarak mergetool ile oluşturulan gereksiz dosyaları silin, genellikle mergetool * .orig uzantılı ek bir dosya oluşturur. Lütfen bu dosyayı yalnızca bir kopyası olduğu için silin, değişiklikleri yerel olarak düzeltin ve dosyalarınızın doğru sürümünü ekleyin. git add #your_changed_correct_files

  8. Durumu tekrar kontrol et: git status

  9. Değişiklikleri aynı tanımlayıcıya uygulayın (bu, yeni bir ayrı düzeltme kümesini önler): git commit --amend

  10. Ana şubeye bas : git push (Git deponuza)

28
16 апр. Cevap Chhabilal 16 nisan verildi . 2015-04-16 10:02 '15 10:02 2015-04-16 10:02

Basitçe söylemek gerekirse, depolardan birindeki değişikliklerin önemli olmadığını ve diğer değişikliklerin lehine olan tüm değişikliklere izin vermek istiyorsanız, şunu kullanın:

 git checkout . --ours 

deponuzun lehine değişiklik yapılmasına izin vermek veya

 git checkout . --theirs 

başka bir veya ana havuzun lehine değişikliklere izin ver .

Veya, dosyalarda p4merge , p4merge birleştirme p4merge söylemek ya da daha önce ayarlamış olduğunuz herhangi bir adı yazmak için GUI birleştirme aracını kullanmanız gerekir.

 git mergetool -t p4merge 

ve dosyayı tamamladıktan sonra bir sonrakini açmak için kaydetmeniz ve kapatmanız gerekecektir.

27
26 янв. Mohamed Selim tarafından 26 Ocak tarihinde cevaplandı 2016-01-26 20:42 '16, 20:42, 2016-01-26 20:42

Birleştirme ihtilaflarını, diğerleri ayrıntılı olarak açıklandığı gibi birkaç yolla düzeltebilirsiniz.

Bence asıl anahtar, değişikliklerin yerel ve uzak depolarla nasıl aktığını bilmesi. Bunun anahtarı izleme branşlarını anlamaktır. İzleme şubesini, benim yerel, gerçek dosya dizinim ve uzaktan kumanda ile aramdaki "ortadaki eksik kısım" olarak düşündüğümü buldum.

Bunu önlemek için şahsen iki şeye alışmıştım.

Bunun yerine:

 git add . git commit -m"some msg" 

İki dezavantajı var -

a) Tüm yeni / değiştirilmiş dosyalar eklenir ve bazı istenmeyen değişiklikler içerebilir.
b) Önce dosya listesini göremezsiniz.

Öyleyse:

 git add file,file2,file3... git commit # Then type the files in the editor and save-quit. 

Bu şekilde, hangi dosyaların eklendiğini daha kasıtlı olarak tartışıyorsunuz ve ayrıca listeyi kaydırıp mesajın düzenleyicisini kullanarak biraz daha düşünebilirsiniz. -m seçeneği yerine tam ekran düzenleyiciyi kullandığımda mesaj iletmemi geliştirdiğini de biliyorum.

[Güncelleme - zaman geçtikçe daha fazlasını değiştirdim:

 git status # Make sure I know whats going on git add . git commit # Then use the editor 

]

Ayrıca (ve durumunuza daha uygun bir şekilde) kaçınmaya çalışıyorum:

 git pull 

veya

 git pull origin master.