Git birleştirme çakışmalarını çekme sırasındaki değişikliklerin lehine çözme


1225

Git birleştirme çakışmasını çekilen değişiklikler lehine nasıl çözebilirim?

Temel olarak, çatışmasız değişiklikleri git mergetoolkorurken bir süre ile tüm çatışmalardan geçmek zorunda kalmadan, çalışan bir ağaçtan tüm çakışan değişiklikleri kaldırmam gerekiyor . Tercihen bunu çekerken yapmak, daha sonra değil.




3
@DanDascalescu Kabul edilen cevap bu soruları cevaplamıyor, bu yüzden açıkça bir kopya değil. Ayrıca, bu diğer soru oldukça belirsiz: ne sorulduğunu söylemek çok zor. Sonuçta seninle aynı fikirde değilim. Bunun ne anlamı var?
sanmai

2
@sanmai İki cevabınız var - ve onlardan birini kabul ettiniz. Bir cevapta ne beklediğinizi ve burada ne kadar daha fazla ayrıntı istediğinizi açıklayabilir misiniz?
Edward Thomson

2
@EdwardThomson iyi, aslında ilk cevap için bu saygınlığı vermeyi düşünüyordum, ama sorarsanız daha iyi bir yanıtın gelip gelmediğini görebilirim
sanmai

Yanıtlar:


1218
git pull -s recursive -X theirs <remoterepo or other repo>

Veya, varsayılan depo için:

git pull -X theirs

Zaten çakışmış durumdaysanız ...

git checkout --theirs path/to/file

40
-s recursiveBurada varsayılan birleştirme stratejisi olduğu için gereksiz olduğunu unutmayın . Böylece basitleştirebilirsiniz git pull -X theirs, ki bu temel olarak eşdeğerdir git pull --strategy-option theirs.

5
Bunu yaparsam MERGINGdevlete geri dönerim . Sonra git merge --aborttekrar deneyebilirim, ama her seferinde bir birleşme meydana gelir. … Yine de akıntıya bir rebase itildiğini biliyorum, belki de buna neden oluyor?
Benjohn

22
Dikkatli ol git checkout --theirs path/to/file. Rebase sırasında kullandı ve beklenmedik sonuçlar aldı. Dokümanda
Vuk Djapic

10
Kılavuzgit checkout --theirs/--ours path sayfasının, birleştirilmemiş yollar için çalıştığını belirttiğini unutmayın . Dolayısıyla, yolda hiçbir çakışma olmasaydı, bu komut zaten bir araya getirilmeyecek bir şey yapmaz. Bu, örneğin bir alt klasörün tümünün 'onların' sürümünü istediğinizde sorunlara neden olabilir. Bu durumda, böyle bir git checkout MERGE_HEAD pathsağlama karması yapmak veya kullanmak daha güvenli olacaktır .
fsw

4
git pull -X theirsçakışmalar varsa birleştirme taahhüdü oluşturur (örneğin, başka bir komutan git push -fuzaktan kumandaya kaçarsa). Birleştirme taahhütleri istemiyorsanız bunun yerine çalıştırın git fetch && git reset --hard origin/master.
Dan Dascalescu

985

Özyinelemeli "onların" strateji seçeneğini kullanabilirsiniz :

git merge --strategy-option theirs

Gönderen adam :

ours
    This option forces conflicting hunks to be auto-resolved cleanly by 
    favoring our version. Changes from the other tree that do not 
    conflict with our side are reflected to the merge result.

    This should not be confused with the ours merge strategy, which does 
    not even look at what the other tree contains at all. It discards 
    everything the other tree did, declaring our history contains all that
    happened in it.

theirs
    This is opposite of ours.

Not: Adam sayfa söylediği gibi, "bizimki" birleştirme stratejisi seçeneği "bizimki" birleştirme çok farklıdır strateji .


İşte daha ayrıntılı açıklama: lostechies.com/joshuaflanagan/2010/01/29/…
mPrinC

227
Ayrıca git checkout --theirstek bir çakışan dosya üzerinde çalışmak için
dvd

48
Zaten uyuşmazlık çözümü durumundaysanız bu çalışmaz. Bu durumda çözmenin en iyi yolunun git checkout <ref to theirs> -- the/conflicted.file; ve sonra git adddeğişiklikleri.
ThorSummoner

54
@ThorSummoner Bu durumda, git checkout - theirs yolu / / / dosyası vardır. Bu şekilde, doğru karmayı manuel olarak aramak zorunda kalmazsınız.
Ikke

8
@Ikke Bana sorarsanız, bu temel olarak kendi cevabı (ve kabul edilen cevap) olmalıdır.
ThorSummoner

473

Zaten çakışmış durumdaysanız ve yalnızca tümünü kabul etmek istiyorsanız :

git checkout --theirs .
git add .

Bunun tam tersini yapmak istiyorsanız:

git checkout --ours .
git add .

Bu oldukça sert, bu yüzden yapmadan önce her şeyi böyle silmek istediğinizden emin olun.


47
veya .teslim almak istediğiniz nokta yerine dosyaları kullanmayın ve belirtmeyin. daha az "sert" ve tam olarak ne yapmak istediğinizi varsayalım.
manroe

10
dosya diğer daldan kaldırıldıysa çalışmaz: '<file>' kendi sürümüne sahip değil
Japster24

3
Yapabilseydim daha fazla oy verirdim, her seferinde bu cevaba geri dönmeye devam et.
tarikki

6
git add -uBunun yerine, sürüm denetimi altında olmayan dosyaları atlamak için kullanın .
Sudipta Basak

3
Varsayımsal durum, bir dosyada üç değişiklik, biri çelişkili, ikisi çatışmasız, bu çözüm çelişkili olmayan değişiklikler uygular mı ve çelişkili değişikliği bizimkine çözer mi? Yoksa sadece bizimkinin kendi versiyonlarındaki çelişkili olmayan değişiklikleri göz ardı eder mi?
pedromarce

222

Tamam, sadece içinde bulunduğum senaryoyu hayal et:

Bir merge, ya da belki bir cherry-pick, teşebbüs edersiniz ve

$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

Şimdi, çakışan dosyayı görüntülüyorsunuz ve değişikliklerinizi gerçekten korumak istemiyorsunuz. Yukarıdaki durumumda, dosya IDE'min otomatik olarak eklediği yeni bir satırda çakıştı. Değişikliklerinizi geri almak ve değişikliklerini kabul etmek için en kolay yol:

git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

Bunun tersi (gelen sürümün sürümünüzle üzerine yazılması)

git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

Şaşırtıcı bir şekilde, bu cevabı internette çok kolay bulamadım.


15
Bir yerine getirmekte olup, bu not git statusarasında checkoutve addşekilde, dosya hala gösterir "her ikisi de değiştirilmiş".
piskopos

Çakışan durumdaki tüm dosyalar için bunu yapmanın bir yolu olup olmadığını biliyor musunuz? Eğer öyleyse cevabınıza hoş bir uzantı olurdu.
Drew Noakes

2
Bunu yapıyorum: git reset --hard ve sonra git pull [remote server name] [branch name] -Xtheirs(birleştirme işlemini geri alır, sonra yeni şeyleri eşyalarımın üzerine çeker) - bu ne istediğinizden emin değilim.
ssaltman

38

git pull -X theirsCevaplar çirkin birleştirme taahhüt oluşturması veya çıkarabilir

hata: Aşağıdaki dosyalarda yaptığınız yerel değişikliklerin birleştirme işleminin üzerine yazılır:

Repo dosyalarındaki yerel değişiklikleri, örneğin her zaman bir kaynağın aynası olması gereken bir istemcide yoksaymak istiyorsanız, bunu çalıştırın ( masteristediğiniz dalla değiştirin ):

git fetch && git reset --hard origin/master

O nasıl çalışır? git fetchyapar git pullama birleştirme olmadan . Ardından git reset --hard, çalışma ağacınızı son işlemle eşleştirir. Repo dosyalara yerel değişikliklerin tümü edilecek atılır , ancak yeni yerel dosyalar yalnız bırakılacaktır.


1
+1 - git fetch && git reset --hard {remote}/{branch}sorunumu çözen şey buydu. Ben tamamen bir şube "onların" durumu lehine kendi değişiklikleri hendek gerekiyordu, ama git pull -X theirsbazı taşınmış / yeniden adlandırılmış dosyaları boğdu. Teşekkürler!
Ivaylo Slavov

23

Git birleştirme işleminden sonra, çakışmalar olursa ve sizin veya onların

git checkout --theirs .
git checkout --ours .

Bunu çakışan yığın başına nasıl yapabilirim? Yukarıdakiler, dosya düzeyinde çalışır ve çakışan bir dosyanın sahip olabileceği çakışan olmayan parçaları atar.
Jani

21

Belirli bir daldaki sürümle olan tüm çakışmaları gidermek için:

git diff --name-only --diff-filter=U | xargs git checkout ${branchName}

Bu nedenle, zaten birleştirme durumundaysanız ve çakışan dosyaların ana sürümünü korumak istiyorsanız:

git diff --name-only --diff-filter=U | xargs git checkout master

Ve boru xargs'a erişimi olmayan pencerelerdeki insanlar için bu nasıl tercüme edilir?
tsemer

Yaptığınız değişiklikleri tamamen atlamaz mı? Çatışma halinde olmayanlar bile?
Valentin Heinitz

Sonunda bunu yaptım. Ne yazık ki, daha sonra bu değişiklikleri uygulamak için a git cherry-pick --continue veya bir git commit --allow-emptykomut gerektirir ve arkasında komutun gerekli olduğu hiçbir sistem yoktur, bu da bunu otomatikleştirmeyi bir acı haline getirir. Şu anda bunu bir .git/COMMIT_EDITMSGdosyanın varlığını test ederek çözüyorum ama bu kibirli ve kırılgan görünüyor ve henüz her zaman işe yaradığına henüz ikna olmadım.
Konrad Rudolph

Bu iyidir, eğer bazılarını manuel olarak çözerseniz (ve yaparsanız git add), geri kalanını bu şekilde toplu olarak çözebilirsiniz.git checkout --ours/ git checkout --theirsde yararlıdır.
rcoup

18

Lütfen bazen bunun işe yaramayacağını unutmayın :

git checkout - yolumuz / dosya / dosya

veya

git checkout --the / to / file yolu

Bunun yerine, HEAD'in ve MERGE_HEAD onların olduğunu varsayarak yaptım

git checkout HEAD -- path/to/file

veya:

git checkout MERGE_HEAD -- path/to/file

Bunu yaptıktan ve iyiyiz:

git add .

Daha fazla bilgi edinmek istiyorsanız, buradaki muhteşem torek yayınına bakın: git checkout --ours, birleştirilmemiş dosyalar listesinden dosyaları kaldırmaz


12

VS Kodu (entegre Git) IDE Kullanıcıları:

Çakışma dosyasında gelen tüm değişiklikleri kabul etmek istiyorsanız , aşağıdaki adımları uygulayın.

1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming

Benzer şekilde , Her İkisini de Kabul Et, Tüm Akımı Kabul Et vb. Gibi diğer seçenekler için de yapabilirsiniz .


2
Bu, yalnızca tek bir dosya için çalışıyor gibi görünüyor, ancak çakışan tüm dosyalar değil.
Yoryo

1

next-versionDeğişen dosyalara tonlarca silme işlemiyle uzun süredir devam eden bir şubem vardıdevelop , her iki dalda farklı yerlere eklenen dosyalar .

next-versionŞube içeriğinin tamamını içeri almak istedimdevelop .

Benim için çalışan yukarıdaki komutların kombinasyonu:

git merge -X theirs next-version
# lots of files left that were modified on develop but deleted on next-version
git checkout next-version .
# files removed, now add the deletions to the commit
git add .
# still have files that were added on develop; in my case they are all in web/
git rm -r web

Yeni bir cevap değil, sadece birçok cevabın bitlerini birleştirerek, kısmen tüm bu cevaplara ihtiyacınız olabileceğinden emin olmak için .


1

Zaten çakışmış durumdaysanız ve yolu tek tek kontrol etmek istemiyorsanız. Deneyebilirsin

git merge --abort
git pull -X theirs

-1

itibaren https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging

Bu temelde sahte bir birleştirme yapacak. Her iki dalda da ebeveyn olarak yeni bir birleştirme taahhüdü kaydeder, ancak birleştirdiğiniz şubeye bile bakmaz. Sadece mevcut dalınızdaki tam kodun birleştirilmesinin sonucu olarak kaydeder.

$ git merge -s ours mundo

'Bizim' stratejisi ile yapılan birleşme.

$ git diff HEAD HEAD~

Şu anda bulunduğumuz şube ile birleşmenin sonucu arasında bir fark olmadığını görebilirsiniz.

Bu genellikle Git'i daha sonra birleştirme yaparken bir dalın zaten birleştirildiğini düşünmesi için faydalı olabilir. Örneğin, bir sürüm dalından ayrıldığınızı ve bunun üzerinde bir noktada ana dalınızla birleştirmek isteyeceğiniz bazı çalışmalar yaptığınızı varsayalım. Bu arada, master'daki bazı hata düzeltmelerinin sürüm şubenize bildirilmesi gerekir. Bugfix dalını sürüm dalına birleştirebilir ve aynı dalı -s bizimki aynı dalı ana dalınıza birleştirebilirsiniz (düzeltme zaten orada olsa bile), böylece daha sonra sürüm dalını yeniden birleştirdiğinizde, bugfix'den çakışma olmaz.

Ustanın yeni bir konu dalındaki değişiklikleri yansıtmasını istiyorsam faydalı bulduğum bir durum. -Xtheirs'in bazı durumlarda çatışma olmadan birleşmediğini fark ettim ...

$ git merge -Xtheirs topicFoo 

CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.

Bu durumda bulduğum çözüm

$ git checkout topicFoo

topicFoo, ilk önce -s bizimki stratejisini kullanarak birleştirme, bu sadece topicFoo'nun durumu olan sahte taahhüdü yaratacaktır. $ git merge -s bizimki usta

oluşturulan birleştirme taahhüdünü kontrol et

$ git log

şimdi ana şubeye göz at

$ git checkout master

konu dalını birleştirin, ancak bu sefer -Xtheirs özyinelemeli stratejiyi kullanın, bu size topicFoo durumuyla bir ana dal sunacaktır.

$ git merge -X theirs topicFoo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.