Git'te “bizim” ve “onların” tam anlamı nedir?


323

Bu çok basit bir soru gibi gelebilir, ama cevap aradım ve şimdi eskisinden daha fazla kafam karıştı.

Şubemizi diğer şubemle birleştirirken git bizim "bizim" ve "onların" ne anlama geliyor? Her iki dal da "bizim" dir.

Birleştirme çatışması "bizim" her zaman iki sürümün üst görüntüleniyor mu?

"Bizim" her zaman birleşme başladığında HEAD'ın işaret ettiği şubeye işaret ediyor mu? Eğer öyleyse, neden "bizimki" gibi sahiplenici bir zamir yerine referans olarak belirsiz olan (her iki dal teknik olarak bizim olduğu için) açık bir iyelik referansı kullanmıyorsunuz?

Ya da sadece şube adını kullanın ("bizimkisi" demek yerine "yerel usta" ya da böyle bir şey söyleyin)?

Benim için en kafa karıştırıcı kısmı, belirli bir şubenin .gitattributes dosyasında belirtmem. Diyelim ki test dalında aşağıdaki .gitattributes dosyası var:

config.xml merge=ours

Şimdi ödeme yapıyorum ve HEAD'ı master'a yönlendirip testte birleştiriyorum . Yana usta olan ours ve testin 'ın .gitattributes hatta bir etkisi olmayacaktır, teslim edilmez? Eğer bir etkisi varsa, üstat şimdi "bizim" olduğundan, ne olacak?

Yanıtlar:


374

Burada kafanız karıştığından şüpheleniyorum çünkü temelde kafa karıştırıcı. İşleri daha da kötüleştirmek için, bir rebase yaparken tüm bizim / onların işleri rolleri değiştirir (geri gider).

Sonuçta, bir sırasında git merge, "bizimki" dal sen birleştirme ediyoruz dalına atıfta içine :

git checkout merge-into-ours

ve "onların" dalı birleştirdiğiniz (tek) dalı ifade eder:

git merge from-theirs

ve burada "bizimki" ve "onların" "onların" senin zaten muhtemelen, "onların" öyleydin biri olmadığından olsa bazı mantıklı üzerinde kaçtın zaman git merge.

Gerçek şube adını kullanmak oldukça havalı olsa da, daha karmaşık durumlarda dağılıyor. Örneğin, yukarıdakiler yerine şunları yapabilirsiniz:

git checkout ours
git merge 1234567

burada ham taahhüt kimliği ile birleşiyorsunuz. Daha da kötüsü, bunu bile yapabilirsiniz:

git checkout 7777777    # detach HEAD
git merge 1234567       # do a test merge

bu durumda ilgili şube adı yoktur !

Sanırım burada çok az yardım var, ama aslında, gitrevisionssözdiziminde , çakışan birleştirme sırasında dizindeki bireysel bir yola numarayla başvurabilirsiniz.

git show :1:README
git show :2:README
git show :3:README

Aşama # 1, dosyaların ortak atasıdır, aşama # 2, hedef şube sürümüdür ve aşama # 3, birleştirdiğiniz sürümdür.


"Bizim" ve "onların" kavramlarının bu sırada takas edilmesinin nedeni, rebaserebase'in bir dizi kiraz toplaması yaparak anonim bir şubeye (müstakil HEAD modu) çalışmasıdır. Hedef dal, anonim daldır ve birleştirme dalının orijinal (rebase öncesi) dalınızdır: bu nedenle "--ours", anonim bir rebase'in inşa edildiği anlamına gelirken "--theirs", "şubemizin yeniden temellendiği" anlamına gelir .


Gitattributes girişine gelince: bunun bir etkisi olabilir : "bizimki" gerçekten "dahili # 2 kullanımı" anlamına gelir. Ancak belirttiğiniz gibi, aslında o sırada yerinde değildir, bu yüzden burada bir etkisi olmamalıdır ... iyi, başlamadan önce çalışma ağacına kopyalamazsanız değil.

Ayrıca, bu arada, bu bizim ve onların tüm kullanımları için geçerlidir, ancak bazıları bir dosya düzeyinde ( -s oursbirleştirme stratejisi için; git checkout --oursbir birleştirme çatışması sırasında) ve bazıları parça parça ( -X oursveya -X theirsbir -s recursivebirleştirmek). Hangi muhtemelen herhangi bir karışıklık ile yardımcı olmaz.

Yine de bunlar için daha iyi bir isim bulamadım. Ve: VonC'ningit mergetool bunlara "yerel" ve "uzak" dediği daha fazla isim tanıtan başka bir soruya cevabına bakınız !


28
+1. Bizimki ve onların geri dönüşü sırasında tersine çevrilmesi hakkında, ayrıca bakınız: stackoverflow.com/a/2960751/6309 ve stackoverflow.com/a/3052118/6309
VonC

1
İki şey birbiriyle "birleşir". Birleştirme gerçekleştiğinde, her iki taraf da "birbirine" birleşir. İki taraftan birinin "hiçbir şeye karışmamasını" söylemenin yanlış olacağını düşünüyorum. İlgili şube adı yoksa (işaret ettiğiniz gibi) ilgili taahhüt adları vardır ("bizimki" ve "onların" yerine "7777777" ve "1234567's" diyebilirsiniz). Rebase sırasında neler olduğunu anlıyorum ve hiç de kafa karıştırıcı olduğunu düşünmüyorum. Bence "HEAD" ve "gelen", "bizim" ve "onların" dan daha iyi çalışır çünkü her zaman bir "HEAD" (müstakil olsun ya da olmasın) vardır.
CommaToast

15
Sanırım kafa, özün kaynağı olan kimlik kaynağı olan zihnin yeri olduğundan, HEAD'in "benim" ("bizim") olarak işaret ettiği her şeyi düşünmek biraz daha mantıklı. Sanırım ben ve HEAD iki tane yapıyor). Başka bir şey yoksa, bu sadece iyi bir anımsatıcı cihaz olacaktır.
CommaToast

1
Olduğu söyleniyor, yine de rebasing gibi bir şey yapmadan önce tüm repo fiziksel bir kopyasını yapmak istiyorum ...: D
CommaToast 17:15

3
"bu durumda hiçbir şube adı yoktur!" ... Bu yüzden bunun yerine komut yorumu / karma kullanmalıdır. Ellerini ne alabilirse. Pratikte her şey "bizimkinden" ve "onlarınkinden" daha iyi olurdu. Bu karışıklığın kaç binlerce dev saat içinde buharlaştığını merak ediyorum. git'in C ++ 'ın "en sinir bozucu ayrışmasına" cevabı;)
Jarrod Smith

49

Git'teki ' bizim ', git tarihinin yetkili / kanonik kısmına sahip orijinal çalışma dalına atıfta bulunuyor.

' Onlarınki ', yeniden baslanabilmek için çalışmayı tutan sürüme işaret eder (mevcut dalda yeniden oynatılacak değişiklikler).

Bu yapıyor (örneğin rebasing farkında değildir kişilere takas gibi görünebilir git rebase) aslında (bir beklemeye işinizi alıyor onlarınki ise kanonik / ana tarihine üzerine yeniden oynatmak için sırayla) bizimki biz rebasing çünkü, bizim üçüncü taraf çalışması olarak değişir.

İçin dokümantasyon taahhütgit-checkout başına Git> = 2.5.1'de açıklanmıştır :f303016

--ours --theirs

Dizinden yolları kontrol ederken birleştirilmemiş yollar için 2. aşamaya ('bizim') veya # 3'e ('onların') bakın.

Not olduğunu sırasında git rebaseve git pull --rebase, 'bizimki' ve takas 'onların' görünebilir; --ourssürümden daldaki değişikliklerin yeniden temel alınmasını sağlarken --theirs, yeniden çalışmakta olduğunuz çalışmanızı tutan daldan sürüm verir.

Bunun nedeni rebase, uzaktaki tarihe paylaşılan kanonik olan gibi davranan bir iş akışında kullanılması ve yeniden adlandırdığınız dalda yapılan çalışmayı, entegre edilecek üçüncü taraf işi olarak ele almanız ve geçici olarak rolünü üstlenmenizdir. Rebase sırasında kanonik tarihin koruyucusu. Kanonik tarihin koruyucusu olarak, uzak oursdaldan geçmişi (yani "ortak kanonik tarihimiz") olarak görmeniz gerekirken, yan dalınızda yaptığınız şey theirs(yani "bir katılımcının üzerine yaptığı çalışma").

Çünkü git-mergeşu şekilde açıklar:

bizim

Bu seçenek, sürümümüzü tercih ederek çakışan yakışıklıların temiz bir şekilde otomatik olarak çözülmesini sağlar. Diğer ağaçtan tarafımızla çelişmeyen değişiklikler birleştirme sonucuna yansır. İkili dosya için tüm içerik tarafımızdan alınır.

Bu, diğer ağacın ne içerdiğine bile bakmayan bizim birleştirme stratejimizle karıştırılmamalıdır. Diğer ağacın yaptığı her şeyi atar, tarihimizin içinde olan her şeyi içerdiğini beyan eder.

onların

Bu bizimkinin tersidir.

Dahası, burada bunların nasıl kullanılacağı açıklanmaktadır:

Birleştirme mekanizması ( git mergeve git pullkomutları), arka uç birleştirme stratejilerinin -sseçenekle seçilmesini sağlar . Bazı stratejiler, ve / veya -X<option>argümanları verilerek geçirilebilen kendi seçeneklerini de alabilir .git mergegit pull


Yani bazen kafa karıştırıcı olabilir, örneğin:

  • git pull origin master-Xoursbizim yerel nerede , -Xtheirsonların (uzak) şubesi
  • git pull origin master -r-Xoursonlarınki nerede (uzak), -Xtheirsbizimki

Bu yüzden 2. örnek birincinin tersidir, çünkü şubemizi uzak olanın tepesine dayandırıyoruz, bu nedenle başlangıç ​​noktamız uzak olanı ve değişikliklerimiz harici olarak değerlendiriliyor.

git mergeStratejiler ( -X oursve -X theirs) için benzer .


2
bu cevap güncel değil => "git merge --ours" geçerli bir seçenek değil
Alexander Mills

Cevap bahsetmedik @AlexanderMills git mergeama git pullve git checkoutörnek olarak. Bu parametreyi ile git mergekullanmak istiyorsanız, kullanmalısınız -X ours. İçin --ourssözdizimini kullanmaya devam edebilirsiniz git checkout. Cevabı daha fazla açıkladım.
kenorb

46

Bunun cevaplandığını biliyorum, ancak bu sorun beni birçok kez karıştırdı, hatırlamama yardımcı olmak için küçük bir referans web sitesi hazırladım: https://nitaym.github.io/ourstheirs/

İşte temel bilgiler:

Merges:

$ git checkout master 
$ git merge feature

Sürümü şurada seçmek istiyorsanız master:

$ git checkout --ours codefile.js

Sürümü şurada seçmek istiyorsanız feature:

$ git checkout --theirs codefile.js

rebases:

$ git checkout feature 
$ git rebase master 

Sürümü şurada seçmek istiyorsanız master:

$ git checkout --ours codefile.js

Sürümü şurada seçmek istiyorsanız feature:

$ git checkout --theirs codefile.js

(Bu elbette tüm dosyalar için)


1
Bu web sitesi çok yardımcı. Akış şeması stili ve renk kodlu kelimeler, web sitesinin anlaşılmasını SO cevaplarından daha kolay hale getirir. Teşekkür ederim.
Ron

10
  • Bizimki : Bu şu anda bulunduğunuz şubedir.
  • Theirs : Bu, eyleminizde kullanılan diğer dal.

Eğer dal üzerinde Yani eğer salım / 2.5 ve şube birleştirme özellik / yeni-düğmeleri içine, bulunduğu haliyle ardından içerik salımı / 2.5 ne olduğunu bizim üzerinde bulduğumuz gibi ifade eder ve içerik özellik / yeni-düğmeleri neler olduğunu onlarınki eder için. Birleştirme işlemi sırasında bu oldukça basittir.

Çoğu insanın düştüğü tek sorun rebase davasıdır . Normal bir birleştirme yerine yeniden temel alırsanız, roller değiştirilir. O nasıl? Bunun nedeni yalnızca yeniden temel oluşturmanın çalışma şeklidir. Rebase'in böyle çalışmasını düşünün:

  1. Son çektiğinizden beri yaptığınız tüm taahhütler kendi dallarına taşındı, buna BranchX adını verelim .
  2. Geçerli şubenizin başına ödeme yaparsınız, yaptığınız yerel değişiklikleri atarsınız, ancak bu şekilde başkalarının söz konusu dal için zorladığı tüm değişiklikleri alırsınız.
  3. Şimdiki BranchX'teki her taahhüt, şu anki branşınızda eskiden yeniye doğru kiraz olarak toplanır.
  4. BranchX tekrar silinir ve bu nedenle hiçbir tarihte görünmez .

Tabii ki, gerçekte olan bu değil ama benim için güzel bir zihin modeli. Ve 2 ve 3'e bakarsanız, rollerin neden şimdi değiştirildiğini anlayacaksınız. 2 itibariyle, mevcut şubeniz artık değişiklikleriniz olmadan sunucudaki şubedir, bu yüzden bu bizimdir (bulunduğunuz şube). Yaptığınız değişiklikler şu anda sizin geçerli olan ( BranchX ) olmayan farklı bir dalda ve bu değişiklikler (yaptığınız değişikliklere rağmen) onlarınki (eyleminizde kullanılan diğer dal).

Bu, birleştirirseniz ve değişikliklerinizin her zaman kazanmasını istiyorsanız, git'e her zaman "bizimkileri" seçmesini söylersiniz, ancak yeniden birleştirirseniz ve tüm değişikliklerinizin her zaman kazanmasını istiyorsanız, git'e her zaman "onlarınkini" seçmesini söylersiniz.


3

Anlamını açıklamadığını biliyorum ama hangisini kullanacağımı hatırlatmak için kendime küçük bir görüntü yaptım:

resim açıklamasını buraya girin

Umarım yardımcı olur!

PS - bağlantıyı da bir çek ver Nitay cevabı 🙂


3

Notumu buraya göndereceğim, çünkü buraya tekrar tekrar gelmem gerekiyor.

SENARYO 1. Normal geliştirici: Yalnızca dallarla birleştirilemeyen masterve onunla oynamak zorunda olan geliştiricisiniz feature.

Durum 1: Usta bir kraldır. Yeni bağımlılık güncellemeleri içerdiği ve mütevazı değişikliklerinizin üzerine yazmak istediğiniz için featuredalınızı yenilemek istiyorsunuz (= rebase to master) master.

git checkout master
git pull

git checkout feature
git rebase -X ours master

Durum 2: Sen bir kransın. Eğer rebase istediğiniz featurekadar dalını masterdeğişiklikleri. Ancak meslektaşlarınızın sahip olduklarından daha fazlasını yaptınız ve kendi değişikliklerinizi öncelikli olarak kullanmak istiyorsunuz.

git checkout master
git pull

git checkout feature
git rebase -X theirs master

ÖNEMLİ: Gördüğünüz gibi normal geliştiriciler rebaseher sabah egzersiz / kahve gibi tercih etmeli ve tekrar etmelidir .

SENARYO 2. Birleştirme-Anlam: Bir takım liderisiniz ve diğer dalları birleştirmek ve birleştirilmiş bir sonucu doğrudan bir efendiye göndermek istiyorsunuz. masterdeğiştireceğiniz bir daldır.

Durum 1: Master bir kraldır Üçüncü taraf dalını birleştirmek istiyorsunuz, ancak masterbir öncelik. feature... yaşlılarınızın yaptığı bir şubedir.

git checkout feature
git pull

git checkout master
git merge -X ours master

Durum 2: yeni değişiklikler bir kraldır Kıdemli geliştiriciniz bir serin yayınladı featureve masterdaldaki eski ** ler üzerine yazmak istediğinizde .

git checkout feature
git pull

git checkout master
git merge -X theirs master

UNUTMAYIN:: Bir seçmek için bir gece yarısı içinde hatırlamak için masterolduğunu oursHER ZAMAN. Ve theirsbir olan featureonların yapmış olduğu.


2

Gönderen git checkoutbireyin kullanımına:

-2, --ours            checkout our version for unmerged files
-3, --theirs          checkout their version for unmerged files
-m, --merge           perform a 3-way merge with the new branch

Birleştirme çakışmalarını çözerken bunu yapabilir git checkout --theirs some_fileve git checkout --ours some_filedosyayı geçerli sürüme ve gelen sürümlere sıfırlayabilirsiniz.

Dosyayı 3 yönlü birleştirme sürümüne ayarladıysanız git checkout --ours some_fileveya git checkout --theirs some_filesıfırlamak istiyorsanız, bunu yapabilirsiniz git checkout --merge some_file.

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.