Farklı git birleştirme stratejilerini ne zaman kullanırsınız?


429

Git-merge'deki man sayfasında, kullanabileceğiniz bir dizi birleştirme stratejileri vardır.

  • çözüm - Bu, 3 yönlü birleştirme algoritması kullanarak yalnızca iki başlığı (yani geçerli dal ve çektiğiniz başka bir dal) çözebilir. Çapraz-birleştirme belirsizliğini dikkatle tespit etmeye çalışır ve genellikle güvenli ve hızlı kabul edilir.

  • özyinelemeli - Bu, yalnızca 3 yönlü birleştirme algoritması kullanarak iki kafayı çözebilir. 3-yollu birleştirme için kullanılabilecek birden fazla ortak ata varsa, ortak ataların birleştirilmiş bir ağacı oluşturur ve bunu 3-yollu birleştirme için referans ağacı olarak kullanır. Bunun, Linux 2.6 çekirdek geliştirme geçmişinden alınan gerçek birleştirme taahhütlerinde yapılan testlerle yanlış birleşmelere neden olmadan daha az birleşme çatışmasıyla sonuçlandığı bildirilmiştir. Ayrıca bu, yeniden adlandırma içeren birleştirmeleri algılayabilir ve işleyebilir. Bu, bir kolu çekerken veya birleştirirken varsayılan birleştirme stratejisidir.

  • ahtapot - Bu, iki başlıklı vakayı çözer, ancak manuel çözünürlük gerektiren karmaşık birleştirme yapmayı reddeder. Öncelikle konu başlığı kafalarını bir araya getirmek için kullanılması amaçlanmıştır. Bu, birden fazla dalı çekerken veya birleştirirken varsayılan birleştirme stratejisidir.

  • bizimki - Bu, herhangi bir sayıda başlığı çözer, ancak birleştirme sonucu her zaman geçerli dal başıdır. Yan dalların eski gelişim tarihinin yerini almak için kullanılır.

  • subtree - Bu, değiştirilmiş bir özyinelemeli stratejidir. A ve B ağaçlarını birleştirirken, B A'nın bir alt ağacına karşılık gelirse, B ilk önce ağaçları aynı seviyede okumak yerine A'nın ağaç yapısına uyacak şekilde ayarlanır. Bu ayarlama aynı zamanda ortak ata ağacına da yapılır.

Ne zaman varsayılandan farklı bir şey belirtmeliyim? Hangi senaryolar en iyisidir?

Yanıtlar:


305

Çözüme aşina değilim, ama diğerlerini kullandım:

Recursive

Yinelemeli, ileri sarma olmayan birleştirme için varsayılan değerdir. Hepimiz buna aşinayız.

Ahtapot

Birleştirilmesi gereken birkaç ağaç varken ahtapot kullandım. Bunu, birçok dalın bağımsız gelişime sahip olduğu büyük projelerde görüyorsunuz ve hepsi tek bir kafaya gelmeye hazır.

Bir ahtapot dalı, temiz yapabildiği sürece birden fazla başlığı bir taahhütte birleştirir.

Örnek olarak, bir ustası olan bir projeniz ve daha sonra birleştirilecek üç dalınız olduğunu düşünün (onlara a, b ve c deyin).

Bir dizi özyinelemeli birleştirme şöyle görünecektir (özyinelemeyi zorlamadığım için ilk birleştirmenin hızlı ileri olduğunu unutmayın):

özyinelemeli birleştirme serisi

Ancak, tek bir ahtapot birleşmesi şöyle görünür:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

ahtapot birleştirme

Bizim

Bizimki == Başka bir kafaya çekmek istiyorum, ama kafanın getirdiği tüm değişiklikleri atmak istiyorum.

Bu, dalın hiçbir etkisi olmadan bir dalın tarihini tutar.

(Oku: Bu dallar arasındaki değişikliklere bile bakılmıyor. Dallar birleştiriliyor ve dosyalara hiçbir şey yapılmıyor. Diğer dalda birleştirmek istiyorsanız ve her seferinde "dosya sürümümüz veya sürüm "kullanabilirsiniz git merge -X ours)

Alt ağaç

Alt ağaç, başka bir projede geçerli projenizin bir alt diziniyle birleştirmek istediğinizde yararlıdır. Alt modül olarak eklemek istemediğiniz bir kitaplığınız olduğunda kullanışlıdır.


1
Yani Ocotopus'un tek gerçek avantajı ağaçtaki birleştirme taahhütlerinin sayısını azaltmak mı?
Otto

60
Ahtapot birleştirme stratejisi belirtmeniz gerekmez : ikiden fazla dalı ( git merge A B ...) birleştirirseniz otomatik olarak kullanılır .
Jakub Narębski

Konu dışı olduğunuz için özür dilerim, ancak bu ekran görüntülerini yaptığınız araç nedir? Şube tarihinin gerçekten harika / güzel bir görselleştirilmesi gibi görünüyor ...
Bernd Haug

4
linux ortamında olanlar için gitg .
Akash Agrawal

2
Bu ipucu -X oursharika, sadece bana bir saat çalışma kurtardı.
Michael

49

Aslında seçmek isterim sadece iki strateji vardır bizimki sen şube getirdiği değişiklikleri kaldırmasını istiyor fakat tarihte şube tutmak istiyorsanız ve alt ağaç sen 'git-gui' 'gibi (superproject ait alt dizine bağımsız projeyi birleştirme eğer git 'deposu).

ikiden fazla dalı birleştirirken ahtapot birleştirme otomatik olarak kullanılır. çözmek esas olarak tarihsel nedenlerden dolayı ve özyinelemeli birleştirme stratejisi köşe vakaları tarafından vurulduğunuzda .


Ben ölümcül git-write-tree hataları olan iki başlı birleştirme için varsayılan 'özyinelemeli' yerine 'çözmek' seçmek zorunda kaldı. 'Çöz' stratejisi temiz bir şekilde birleşti. Birleştirilen dalda çok sayıda dosyayı hareket ettirmek zorunda kalmış olabilir.
thaddeusmt

@thaddeusmt: İlginç. Mümkünse, "özyinelemeli" birleştirme stratejisinin bu posta listesine gitme hatasıyla ilgili hata raporu gönderebilir misiniz? Şimdiden teşekkürler.
Jakub Narębski

@ JakubNarębski Anlamlı bir hata raporu oluşturmak için yeterli bilgiyi nasıl bir araya getireceğimi bilmiyorum, Git ile bir n00b, özür dilerim. Burada cevabımda bahsettiğim gibi ( stackoverflow.com/a/10636464/164439 ) Benim tahminim benimle her iki dalda değişiklikleri çoğaltmak zorunda kaldım, ve "çözmek" çoğaltılmış değişiklikleri atlamak için daha iyi bir iş yapar.
thaddeusmt

@ JakubNarębski artık sen de seçebilirsiniz onların manuel "ters göre hangi, bizimki . Onlarınki ne sizin için otomatik olarak seçilir Eğer hafifçe anwser güncelleyebilirsiniz etsin, ekleme. Onlarınki seçeneği
SebNag

3
@SebTu: theirsbirleştirme stratejisi (yani --strategy=theirs) yoktur, ancak theirsvarsayılan recursivebirleştirme stratejisi ( --strategy=recursive --strategy-option=theirsveya sadece -Xtheirs) seçeneği vardır.
Jakub Narębski

23

"Çöz" ve "Yinelemeli" birleştirme stratejisi

Özyinelemeli, geçerli varsayılan iki başlı stratejidir, ancak bazı aramalardan sonra nihayet "çözüm" birleştirme stratejisi hakkında bazı bilgiler buldum.

O'Reilly kitabından Git ile Kontrol ( Amazon ) (başka sözcüklerle yazılmış):

Başlangıçta Git birleştirme için varsayılan çözüm "çözüm" idi.

Birden fazla olası birleştirme temeli olan çapraz kesişmeli birleştirme durumlarında, çözümleme stratejisi şu şekilde çalışır: olası birleştirme tabanlarından birini seçin ve en iyisini umun. Bu aslında göründüğü kadar kötü değil. Genellikle kullanıcıların kodun farklı bölümleri üzerinde çalıştığı ortaya çıkıyor. Bu durumda Git, zaten mevcut olan bazı değişiklikleri yeniden düzenlediğini algılar ve yinelenen değişiklikleri atlayarak çakışmayı önler. Ya da, bunlar çatışmaya neden olan küçük değişiklikler ise, en azından çatışmanın geliştiricinin üstesinden gelmesi kolay olmalıdır.

Başarıyla varsayılan özyinelemeli stratejisi ile başarısız "çözmek" kullanarak ağaçları birleştirdik. fatal: git write-tree failed to write a treeHata alıyordum ve bu blog yazısı ( ayna ) sayesinde işe yarayan "-s çözüm" denedim. Hala neden tam olarak emin değilim ... ama her iki ağaçta da yinelenen değişikliklere sahip olduğumu ve bunları düzgün bir şekilde "atladığını" düşündüğüm için düşünüyorum.


3 yollu birleştirme (p4merge) kullanıyorum ve özyinelemeli birleştirme başarısız olduğunda .BASE dosyasına yazılmış çakışmalar vardı. Çözüm stratejisine geri dönmek bu durumda yardımcı oldu.
mrzl


-2

Yukarıdaki yanıtlar tüm strateji detaylarını göstermediği için. Örneğin, bazı cevap ithalat ilgili ayrıntıları eksik resolveseçeneği ve recursivebirçok alt seçenekleri vardır hangi ours, theirs, patience, renormalize, vb

Bu nedenle, gittüm olası özellik özelliklerini açıklayan resmi belgeleri ziyaret etmenizi tavsiye ederim :

https://git-scm.com/docs/merge-strategies

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.