Ezme çekme istekleri git'in birleştirme algoritmasını bozar mı?


17

Şu anda git kodunu yönetmek için VSTS kullanan bir şirket için çalışıyorum. Microsoft'un bir şubeyi birleştirmenin "önerilen" yolu, bir "squash birleşmesi" yapmaktır, yani bu şubeye ilişkin tüm taahhütler, tüm değişiklikleri içeren yeni bir taahhütte ezilir.

Sorun, bir biriktirme öğesi için bir dalda bazı değişiklikler yaparsam, hemen başka bir biriktirme öğesi için başka bir dalda değişiklik yapmaya başlamak istiyor ve bu değişiklikler ilk dalın değişiklik kümesine bağlı mı?

Bu biriktirme listesi öğesi için bir şube oluşturabilir ve ilk dalı temel alabilirim. Çok uzak çok iyi. Ancak, ikinci şube benim için bir çekme isteği yaratmanın zamanı geldiğinde, ilk şube zaten ustaya birleştirildi ve squash birleştirme olarak yapıldığı için git, bir sürü çatışmayı işaretliyor. Bunun nedeni git, ikinci dalın dayandığı orijinal taahhütleri görmemesi, sadece bir büyük squash birleştirmesini görmesi ve böylece ikinci dalı birleştirmek için ilk dalın tüm taahhütlerini tekrar oynatmaya çalışmasıdır. Squash birleşmesinin tepesi, birçok çatışmaya neden oluyor.

Benim sorum şu, bunun üstesinden gelmenin herhangi bir yolu var mı (sadece bir özellik dalını diğerine dayandırmak dışında, iş akışımı sınırlıyor) veya squash birleştirme sadece git'in birleştirme algoritmasını kırıyor mu?

Yanıtlar:


15

Git ile taahhüt eder

  • değişmez,
  • ve yönlendirilmiş asiklik bir grafik oluşturur.

Ezmek, taahhütleri birleştirmez. Bunun yerine, diğer birçok taahhütten gelen değişikliklerle yeni bir taahhüt kaydeder. Yeniden pazarlama benzerdir, ancak taahhütleri birleştirmez. Mevcut bir işlemle aynı değişikliklerle yeni bir işlem kaydetmeye geçmiş yeniden yazma adı verilir . Ancak mevcut taahhütler değişmez olduğu için, bu, “alternatif bir tarih yazmak” olarak anlaşılmalıdır.

Birleştirme, ortak bir atadan yola çıkarak iki komitenin tarihinin (şubelerinin) değişikliklerini birleştirmeye çalışır.

Öyleyse geçmişinize bakalım:

                                 F  feature2
                                /
               1---2---3---4---5    feature1 (old)
              /
-o---o---o---A---o---o---S          master

A ortak atadır, orijinal özellik dalı 1–5, yeni özellik dalı F ve 1–5 ile aynı değişiklikleri içeren ezilmiş işlemdir. Gördüğünüz gibi, F ve S'nin ortak atası A'dır. Git söz konusu olduğunda, S ve 1-5 arasında bir ilişki yoktur. Bu yüzden ustayı bir tarafta S ve diğer tarafta 1–5 ile özellik2 birleştirmek çakışacaktır. Bu çatışmaları çözmek zor değildir, ancak gereksiz ve sıkıcı bir iştir.

Bu kısıtlamalar nedeniyle, birleştirme / ezme ile başa çıkmak için iki yaklaşım vardır:

  • Geçmiş yeniden yazmayı kullanırsınız, bu durumda aynı değişiklikleri temsil eden birden fazla işlem alırsınız. Daha sonra olur rebase taahhüt ezilmiş üzerine ikinci özellik dalı:

                                     F  feature2 (old)
                                    /
                   1---2---3---4---5    feature1 (old)
                  /
    -o---o---o---A---o---o---S          master
                              \
                               F'       feature2
    
  • Veya geçmiş yeniden yazmayı kullanmazsınız, bu durumda fazladan birleştirme taahhütleri alabilirsiniz:

                                     F  feature2
                                    /
                   1---2---3---4---5    feature1 (old)
                  /                 \
    -o---o---o---A---o---o-----------M  master
    

    Feature2 ve master birleştirildiğinde, ortak ata taahhüt edilecektir 5.

Her iki durumda da birleştirme çabanız olacak. Bu çaba, yukarıdaki iki stratejiden hangisini seçtiğinize bağlı değildir. Ama emin olun

  • dallar kısa ömürlüdür, ana daldan ne kadar sürüklenebileceklerini sınırlamak ve
  • ana öğeyi düzenli olarak özellik dalınızla birleştirir veya dalları senkronize tutmak için ana özellik dalını yeniden oluşturursunuz.

Bir ekipte çalışırken, şu anda kimin ne üzerinde çalıştığını koordine etmek yardımcı olur. Bu, geliştirilmekte olan özelliklerin sayısını küçük tutmaya yardımcı olur ve birleştirme çakışmalarının sayısını azaltabilir.


2
Cevabınız, önce ustayla squash-birleştirme yaparsanız feature1, daha sonra birleştirmek isterseniz ne olduğu ile başa çıkmaz gibi görünüyor feature2. Bu durumda, ilk yaklaşım git feature1komutları ezilmiş taahhüdün üzerine yeniden uygulamaya çalıştığında çatışmalara yol açmazken, ikincisi git'in bu taahhütlerin birleştirilmesine gerek olmadığını belirlemesine izin verir mi?
Jez

@Jez Bir PR'yi ezdiğinizde tam olarak bu olur. Geçenlerde manuel olarak bir OSS projesinde bir PR yeniden yazmak zorunda kaldı ( git clonerepo ing ve değiştirilen dosyaları üzerinde kopyalayarak!) Çünkü bir daldan dallı ve sürdürücü ilk dalı ezdi. Benim işimde squash birleşmeleri de yapıyorlar. Bu b, özellik birleştirilene akadar özelliğe bağlı bir özellik üzerinde çalışamayacağım anlamına gelir a.
Deplasman Hesabı

1
Ve bu git için tasarlandığı gibi işe yarayacak bir şeyin gerçekten can sıkıcı bir kırılması değil mi? Bakın, Microsoft ve Github gibi çeşitli kuruluşların aslında bu squash birleşmelerini önerdiğini görüyorum ve bana aptal görünüyorlar.
Jez

1
@Jez Orijinal senaryoda, evet özellik2'yi ustalıkla birleştirdiğinizde çakışmalar elde edersiniz, çünkü 1–5 işlemlerini birleştirmek S'deki aynı değişikliklerle çakışır. Çözüm, özellik2'yi (çözüm 1) yeniden adlandırmak veya hepsi (çözelti 2).
amon

Squash birleştirme işlemlerinin sizin için uygun olup olmadığı, sürüm kontrol geçmişinde neyi kaydetmek istediğinize bağlıdır. Özellik dallarının çok sayıda WIP taahhüdü varsa, squashing, ana daldaki tüm özellik ile tek bir büyük taahhüt verir. Özellik dalının tüm aracı taahhütlerini korumayı tercih ediyorsanız, yeniden basma veya birleştirme kullanın.
amon

11

Squash birleştirme, squash tarafından kaldırılan herhangi bir taahhüt içeren şubeler için birleştirme algoritmasını bozar. Başka bir deyişle, bazlar viral. Bir dalı yeniden temellendirirseniz, o şubeye bağlı olan diğer dalları yeniden temellendirmeniz gerekir. Eğer rerere kullanırsanız , yerel deponuzda manuel olarak çözdüğünüz birleştirme çakışmalarının tekrar manuel olarak çözülmesi gerekmez, ancak bu diğer insanlar tarafından çözülen çatışmalara yardımcı olmaz.

Bu nedenle buradaki yazılmamış kuralımız, başka hiç kimse özellik dalınıza bağlı olmadığı sürece ezilmenin uygun olması, bu da belki% 90'lık bir durumdur. Aksi takdirde, düz birleştirme herkesin sorunlardan kaçınmasına yardımcı olur.


Ana tarihte ezilmiş bir bağlılığa sahip olmanın bir yolu ve bir özellik dalı, ayrı bir kabak-sadece dal yapmak için sağlamdı. Diyelim ki bir feature-xyzşubeniz var. Bir oluşturabilir feature-xyz-squashedolarak işlemek aynı başlayarak şube feature-xyz, şube git cherry-pickgelen kaydedilmesini feature-xyziçin feature-xyz-squashed, onları orada ezmek ve birleştirme feature-xyz-squashediçin master. feature-xyzO zaman birleştirmemelisin . Bazen yukarıdakiler mantıklıdır (örneğin, şifreleri gizlenmiş olan taahhütleri dahil etmek istemezsiniz), ancak bu bir çözümdür, neredeyse en iyi uygulamadır.
9000
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.