Git Cherry-pick ve Birleştirme İş Akışı


302

Bir repo'nun koruyucusu olduğumu ve bir katkıda bulunanın değişikliklerini çekmek istediğimi varsayarsak, birkaç olası iş akışı vardır:

  1. Her cherry-pickbiri uzaktan (sırayla) taahhüt ediyorum . Bu durumda git, uzak dalla ilgisi olmayan taahhüdü kaydeder.
  2. Ben mergeşube, tüm değişiklikleri çekerek ve (gerekirse) yeni bir "çatışma" taahhüdü ekleyerek.
  3. Her mergebiri uzak daldan ayrı ayrı (sırayla) taahhüt ediyorum , çatışmaların her biri için tek bir grup halinde gruplanmak yerine kaydedilmesine izin veriyorum.
  4. Tamlık için, rebase(seçenekle aynı cherry-pickmı?) Yapabilirsiniz, ancak benim anlayışım bunun katılımcı için karışıklığa neden olabileceğidir. Belki de bu seçenek 1'i ortadan kaldırır.

Her iki durumda da 2 ve 3, git 1'den farklı olarak taahhütlerin dal geçmişini kaydeder.

Tanımlanan yöntemlerden birini cherry-pickveya mergeyöntemleri kullanma arasındaki pro ve con'lar nelerdir? Anladığım kadarıyla, yöntem 2 normdur, ancak tek bir "çatışma" birleştirmesiyle büyük bir taahhüdü çözmenin en temiz çözüm olmadığını hissediyorum.

Yanıtlar:


297

Hem rebase(ve cherry-pick) hem mergede avantajları ve dezavantajları vardır. mergeBurada tartışıyorum ama ikisini de anlamaya değer. (Burada tercih edilen durumları sıralayan alternatif, iyi tartışılmış bir cevap arayın rebase.)

mergedaha fazla tercih edilir cherry-pickve rebasenedenlerden bir çift için.

  1. Sağlamlık . Bir taahhüdün SHA1 tanımlayıcısı onu sadece kendi içinde değil , ondan önce gelen diğer tüm taahhütlerle de ilişkilendirir . Bu size belirli bir SHA1'deki havuzun durumunun tüm klonlarda aynı olduğunu garanti eder. (Teoride) birisinin aynı değişikliğe benzeyen bir şey yapma şansı yoktur, ancak aslında deponuzu bozuyor veya kaçırıyor. Bireysel değişikliklerde kiraz toplayabilirsiniz ve muhtemelen aynıdır, ancak garantiniz yoktur. (Küçük bir ikincil konu olarak, yeni kiraz toplanan taahhütler, aynı kopyada başka bir kiraz seçerse, her ikisi de çalışma kopyalarınız aynı olsa bile tarihte mevcut olacağı için ekstra alan kaplar.)
  2. Kullanım kolaylığı . İnsanlar mergeiş akışını oldukça kolay anlama eğilimindedir . rebasedaha gelişmiş sayılır. Her ikisini de anlamak en iyisidir, ancak sürüm kontrolünde uzman olmak istemeyen insanlar (deneyimlerime göre, yaptıkları işte çok iyi olan, ancak fazladan zaman harcamak istemeyen birçok meslektaşını dahil etti) zaman sadece birleşiyor.

Birleştirme-yoğun iş akışıyla bile rebaseve cherry-pickbelirli durumlar için hala yararlıdır:

  1. Bunun bir dezavantajı merge, karmaşık bir tarihtir. rebaseuzun bir süre taahhütlerin geçmişinizde dağılmasını önler, tıpkı başkalarının değişikliklerinde periyodik olarak birleşmiş olmanız gibi. Aslında onu kullandığım ana amacı bu. Çok dikkatli olmak istediğiniz şey , asla rebasediğer depolarla paylaştığınız kodları kodlamak değildir. Bir taahhüt tamamlandığında, pushbaşkası bunun üzerine iş yapmış olabilir ve yeniden bastırma en iyi şekilde yukarıda tartışılan kopyalamaya neden olur. En kötüsü, çok karışık bir depo ve ince hatalarla sonuçlanabilir, gelip gelmek uzun zaman alacaktır.
  2. cherry-pick temel olarak atmaya karar verdiğiniz bir konu dalından küçük bir değişiklik alt kümesini örneklemek için yararlıdır, ancak üzerinde birkaç yararlı parça olduğunu fark ettiniz.

Bir çok değişikliğin bir arada birleştirilmesini tercih etmek için: sadece çok daha basit. Birçoğuna sahip olduğunuzda, bireysel değişiklik kümelerinin birleştirilmesini yapmak çok sıkıcı olabilir. Git (ve Mercurial ve Bazaar'da) birleştirme çözünürlüğü çok iyi. Çoğu zaman uzun dalları bile birleştirirken büyük sorunlar yaşamazsınız. Genellikle ve sadece bir kez tüm her şeyi birleştirme eğer ben çatışmalar çok sayıda alırım ben yedeklemek ve parça parça birleştirme yeniden çalıştırın. O zaman bile bunu büyük parçalar halinde yapıyorum. Çok gerçek bir örnek olarak, birleştirmek için 3 aylık değerinde değişikliklere sahip olan ve 250000 satır kod tabanında 9000 çakışması olan bir meslektaşım vardı. Ne düzeltme yaptığını bir anda birleştirme bir aylık yetmeyecek do: çatışmalar doğrusal olarak birikir ve de adet sonuçlarında yapıyor yok uzakta9000'den az çatışma. Hala çok iş vardı, ama her seferinde bir taahhütte bulunmaya çalışmak kadar değil.


1
Aslında, teoride Mallory'nin aynı SHA1 ama farklı içeriğe sahip taahhütler oluşturarak deponuzu bozma şansı vardır, muhtemelen pratikte hiç olmayacaktır. :)
Bombe

1
Ha :) Demek istediğim "teoride oranlar o kadar düşük ki gerçekleşmeyeceğine güvenebilirsiniz", ama haklısın topsy-turvy.
quark

"Birleştirme - squash" hakkında ne düşünüyorsun?
cmcginty

@Bombe Mallory başarılı olmak istiyorsa, aynı SHA1 ile orijinal taahhüdü ve ikinci taahhüdü özel olarak oluşturmak zorunda kalacaktı. Öyleyse başka bir soru olabilir: İki (bir şekilde) sahte suçun ortaya çıkma olasılığı nedir ve fark etmiyor musunuz? ;)
João Portela

64
9000 ihtilafı? İşimi bırakıp arı bakıcısı olurdum.
Sebastian Patten

95

Bence kiraz toplama, nadiren gerekli olduğu durumlarda ayrılmalıdır, örneğin doğrudan 'ana' dalda (gövde, ana geliştirme dalı) bazı düzeltmeler yaptıysanız ve bunun da 'maint'e de uygulanması gerektiğini fark ettiyseniz '. İş akışını birleştirme veya rebase (veya "git pull --rebase") üzerine dayandırmalısınız.

Kirazla toplanan veya yeniden temel alınan işlemin Git'in bakış açısından (SHA-1 tanımlayıcısı farklıdır) orijinalinden farklı olduğunu ve bu nedenle uzak depodaki işlemden farklı olduğunu lütfen unutmayın . (Rebase genellikle bununla başa çıkabilir, çünkü yama kimliğini kontrol eder, yani değişiklikleri taahhüt eder, değil).

Ayrıca git'te aynı anda birçok dalı birleştirebilirsiniz: ahtapot birleştirme denir . Ahtapotun birleşmesinin çatışma olmadan başarılı olması gerektiğini unutmayın. Yine de faydalı olabilir.

HTH.


19
Rebase / cherry-picking'in taahhütleri gerçekten "kopyaladığı" ve dolayısıyla orijinal taahhüdün bağlantısını kaybettiği nokta için +1.
studgeek

1
Bu şekilde kiraz toplama yöntemini, sadece hata düzeltmeleri için taahhütleri (belki ÇOK KÜÇÜK özellikler) bir yama hazırlamak için mevcut bir sürüm dalına taşımak için kullanırız. Birden fazla taahhüt içeren özellikler genellikle master tabanlı bir sürüm dalına girmeyi gerektirir.
foxxtrot

3
@ foxxtrot: Başka bir çözüm, bu hatayı sergileyen en eski taahhüde dayanarak bir hata düzeltmesi için ayrı bir dal oluşturmak ve 'maint' ve 'master' olarak birleştirmektir ... ancak bu durumda söz konusu bugfix'in her iki dal için de geçerlidir.
Jakub Narębski

4
@ Jakub Bir hata düzeltme dalı oluşturmak ve birleştirmek için vazgeçilmez olan iki komut: git blamehatayı tanıtan taahhüdü bulmak git branch --containsve dalı nerede birleştireceğinizi belirlemek. Bu
yayında

-10

Taahhüt tarihini temiz tutmanın tek yolu Rebase ve Cherry-pick. Birleştirme kullanmaktan kaçının ve birleştirme çakışması oluşturmaktan kaçının. Gerrit kullanıyorsanız, gerekirse bir projeyi Birleştir'e ve bir projeyi kiraz toplama moduna ayarlayın ve kendinizi deneyin.


bunun soruyu nasıl cevapladığını açıklığa kavuşturmamak, belki bazı örnekler biraz ışık getirebilir.
Adrian Nasui

1
Geçmişinizin düz görünmesi, anlaşılmasının daha kolay olacağı anlamına gelmez.
nicolimo86

Birleştirme, temiz bir geçmişe sahip olmanın olağan yoludur. Kiraz toplama ve rebase çoğunlukla geçmişi değiştirmeniz gereken durumlar için kullanılır. Bu, birleştirmenin her zaman ilk seçenek olması gerektiği anlamına gelir. Çünkü rebase değişti uzaktan kumandalar ve birden fazla kişi ile çalışırken çok tehlikeli olan comit sha`s.
Radon8472

Buradaki adam madalyayı hak ediyor. Aşağı oy kullanmaya devam edeceğini biliyor ama doğru cevap bu. Kudos.
PW Kad

Üzgünüm, şu ana kadar bu yorumları görmedim, lütfen sonuçlandırmadan önce test ortamınızda deneyin ve sizin için neyin işe yaradığını yapın! Birden fazla ürün branşına katkıda bulunan yaklaşık 600 geliştiricim var, geliştiricilerin yerel çalışma alanında ne yaptığını umursamıyorum, entegrasyon için bir değişiklik gönderildiğinde, geliştirme dalını veya bazen serbest bırakma veya hata düzeltme dalını kiraz toplama yapabilmelidir. FYI ... Gerrit kullanıyorum.
Nagaraj Magadum
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.