Belirli dosyalar için Git birleştirme stratejisini seçin (“bizim”, “benim”, “onların”)


207

Ben sonra sonra yeniden temellerin ortasındayım git pull --rebase. Birleştirme çakışmaları olan birkaç dosyam var. Belirli dosyalar için "değişikliklerini" veya "benim" değişikliklerini nasıl kabul edebilirim?

$ git status
# Not currently on any branch.
# You are currently rebasing.
#   (fix conflicts and then run "git rebase --continue")
#   (use "git rebase --skip" to skip this patch)
#   (use "git rebase --abort" to check out the original branch)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:  CorrectlyMergedFile
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add <file>..." to mark resolution)
#
#       both modified: FileWhereIWantToAcceptTheirChanges
#       both modified: FileWhereIWantToAcceptMyChanges

Normalde dosyayı veya bir birleştirme aracını açıp tüm "onların" veya "benim" değişikliklerini el ile kabul ediyorum. Ancak, uygun bir git komutunu kaçırdığımdan şüpheleniyorum.

Ayrıca, her dosya için bir birleştirme stratejisi seçebileceğime dikkat edin, hangi dosyaların çatışmaları vurduğunu muhtemelen çatışmanın ne olduğunu gördüm.


@AbeVoelker Sorunumu çözdüğünü sanmıyorum. Belirli dosyalar için bir birleştirme stratejisi seçmek istiyorum. Ayrıca, yalnızca yeniden paylaşımımdayken hangi birleştirme stratejisini kullanacağımı bileceğim ve hangi dosyaların çakışmaları ve çatışmaların ne olduğunu göreceğim.
Steven Wexler

Bu soruyu daha genel olarak düzenledim: stackoverflow.com/questions/278081/… . Belki bu soruyu bunun bir kopyası olarak kapatabiliriz? Bu uygun mu?

@TheShadow Bu benim için makul görünüyor.
Steven Wexler

Diğer sorunun başlığını yaptığım şeye değiştirmenin uygun olup olmadığından emin değildim, çünkü ikili dosyaları çözme konusunda rol aldım. Diğer soruyu daha önce olana geri yükledim, bu yüzden bu soru hala değer katıyor.

Yanıtlar:


251

Aldığınız her çakışan dosya için şunları belirtebilirsiniz:

git checkout --ours -- <paths>
# or
git checkout --theirs -- <paths>

Gönderen git checkoutdocs

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

--ours
--theirs
Dizinden yolları kontrol ederken birleştirilmemiş yollar için aşama # 2 ( ours) veya # 3 ( theirs) 'e bakın.

Dizin, önceki başarısız birleştirme nedeniyle birleştirilmemiş girişler içerebilir. Varsayılan olarak, dizinden böyle bir girişi kontrol etmeye çalışırsanız, ödeme işlemi başarısız olur ve hiçbir şey teslim alınmaz. Kullanıldığında -fbu birleştirilmemiş girişler yok sayılır. Birleştirmenin belirli bir tarafından gelen içerik --oursveya kullanılarak dizin dışına alınabilir --theirs. İle -m, çalışma ağacı dosyasında yapılan değişiklikler, çakışan özgün birleştirme sonucunu yeniden oluşturmak için atılabilir.


9
Sıkıştırılmış bırakılan tüm dosyalar için dosyalarını kabul etmek mümkün müdür?
aslakjo

41
@aslakjo git rebase -s recursive -X <ours/theirs>veya git merge -s recursive -X <ours/theirs>. Bir rebase için "bizim" ve "onların" birleştirme sırasında bulunduklarından geri alındığını unutmayın. Muhtemelen sadece bir dosya / kabuk küresi de kullanabilirsiniz git checkout --theirs -- *.txt.

2
Çok teşekkürler @Cupcake, ours/theirsrebase ile beklenmedik bir şekilde ters beni deli ediyordu !! (Artık bir rebase'in gerçekten nasıl çalıştığını düşünüyorum, ama hiç de sezgisel değil.)
Dan Lenski

2
@DanLenski rebase genel olarak insanların önce anlaması için gerçekten zor bir araçtır, ancak nasıl çalıştığını anladıktan sonra, onunla her türlü gerçekten güçlü şeyleri yapabilirsiniz.

1
@VincentSels aslında * karakterini maskelemeniz gerekir, aksi takdirde kabuk onu genişletmeye çalışır. yani senin durumunda git checkout --outs -- "**/*.csproj"ne demek istediğini yapacak. Aynısı, örneğin için de geçerlidir git lfs track "*.jpg". CWD'nizde tırnak işaretleri olmadan bazı jpg dosyalarınız varsa, yalnızca bunlar izlenir.
eFloh

117

Bu soru cevaplansa da, git rebase vs merge durumunda "onların" ve "bizim" ifadelerinin ne anlama geldiğine dair bir örnek sunmak. Bu bağlantıya bakın

Git Rebase
theirs aslında rebase durumunda mevcut şubedir . Bu nedenle, aşağıdaki komutlar grubu uzak daldaki geçerli dal değişikliklerinizi kabul ediyor.

# see current branch
$ git branch
... 
* branch-a
# rebase preferring current branch changes during conflicts
$ git rebase -X theirs branch-b

Git Birleştirme
için birleştirme , anlamı theirsve ourstersine çevrilir. Bu nedenle, bir birleştirme sırasında aynı etkiyi elde etmek için , yani geçerli şube değişikliklerinizi ( ours) birleştirilen uzak şube ( ) üzerinde tutun theirs.

# assuming branch-a is our current version
$ git merge -X ours branch-b  # <- ours: branch-a, theirs: branch-b

2
Peki, bu oldukça önemli bir ayrım! açıkladığın için teşekkürler.
51 verboze

26

Not git checkout --ours|--theirsedecek tamamen dosyalarının üzerine ya seçerek, theirsya oursolabilir veya (eğer diğer taraftan geliyor olmayan çatışmalı değişiklikleri varsa, bunlar kaybolur) ne yapmak istediğinizi olmayabilir sürümü.

Bunun yerine dosya üzerinde bir üç yollu birleştirme gerçekleştirmek ve sadece çözmek istiyorsanız çakışan hunks kullanırken --ours|--theirsederken, olmayan çelişkili hunks tutarak yerde iki taraftan, sen başvurmak isteyebilirsiniz git merge-file; bu cevaptaki ayrıntılara bakın .


1
Kaybolacak olan "çelişkili olmayan değişiklikler" ile ilgili olarak - bu yalnızca aynı dosyada başka satırlarda çelişkili olmayan değişikliklerin olduğu veya hizalanmış geçmişlerdeki tüm dosyalardaki tüm değişikliklerin olduğu anlamına gelir?
ktamlyn

2
@ktamlyn "çelişkili olmayan değişiklikler" ile aynı dosyadaki değişiklikleri kastediyorum. Örneğin, iki değiştirilmiş hunks (parçalar) vardır example.txtiçinde ours(aynı zamanda değiştirilebilir versiyonu, bir çakışmış theirsrevizyon) olmayan diğer çakışmış. Bunu yaparsanız git checkout --theirs example.txt, theirsrevizyon sırasında tüm dosyayı körü körüne okuyacak ve farkın çakışmayan kısmı kaybolacaktır.
jakub.g

1
Teşekkürler! "Aynı dosyadaki değişiklikler" bu bağlamda en mantıklı olmasına rağmen bu benim için gerekli bir açıklama oldu.
ktamlyn

Bu, gerçekten bir cevap vermese de, önerilen diğer çözümde önemli bir soruna işaret etmesine rağmen, kabul edilen cevap olmalıdır.
tomasyany

1
Orijinal çakışan dosyaya geri dönmek isterseniz, çalıştırabilirsiniz git checkout --merge <path>.
Andrew Keeton
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.