it-swarm.asia

Tecrübeli geliştiriciler hala birleşme çatışmalarıyla uğraşmak zorunda mı?

Hala eğitimde bir yazılım mühendisiyim, ancak aşağıdaki atasözü birçok kez duydum:

İyi kodlayıcılar birleşme çatışmalarıyla uğraşmak zorunda değildir.

Ne zaman başkalarıyla bir proje üzerinde çalışsam, birleştirme çatışmalarını çözmek için can sıkıcı bir zaman ve çaba harcıyorum. Böylece, bu atasözün ne kadar doğru olduğunu merak etmeye başladım. GitFlow ve agile gibi geliştiricilerin çalışmalarını verimli bir şekilde bölmesini, daha sık işlem yapmasını ve birden çok kod dalını sürdürmesini sağlayan tekniklerin farkındayım, bu nedenle birleştirme çakışmaları çok daha az olasıdır. Ama elbette hala oluyorlar ve potansiyel olarak tahribat yaratabilirler mi?

Başka bir deyişle, deneyimli geliştiriciler birleştirme çatışmalarını çözmek için ne kadar zaman ve çaba kaybediyorlar (projelerinde ne zaman çalışabilirler)? Mevcut teknikler, birleşme çatışmalarının etkilerini gerçekten yok edebilir mi?

57
lemeneux

İyi geliştiricilerin hiçbir zaman birleştirme çatışmaları olmadığını söylemek biraz gariptir, ancak kesinlikle kaç kez meydana gelebileceklerini azaltabilirler. Yazılım geliştirmenin bir takım etkinliği olduğunu hatırlamak da çok önemlidir. Ekiplerin diğer üyelerinin eylemleri de birleşme çatışması olasılığını artırabilir veya azaltabilir.

İlk olarak, birleşme çatışmalarının ortak yollarını anlamak önemlidir:

  • İki kişi aynı kod satırında farklı değişiklikler yapar
  • Birisi tüm satırı yeniden biçimlendirmeye karar verir, böylece her satır değişir
  • Bir dosyayı silme ve sonra değiştirme (bu bir ağaç çakışması)
  • Kod aynı anda iki farklı kişi tarafından silinir ve eklenir (Visual Studio .vsproj Dosyalar)

Geliştirme takımlar bu durumlardan kaçınmanın yollarını bulmuştur:

  • Her ekip üyesinin kodun farklı bölümlerinde çalıştığından emin olun (yani görev atamasında ele alınır)
  • Tüm satış kodunu yeniden biçimlendirmenin gerekli olmaması için boşluk veya sekme, adlandırma standartları vb. Kullanmanız gerektiğini belirleyen kod standartları
  • GitFlow, böylece herkes kendi şubesinde çalışıyor ve Çekme İsteği aşamasında çakışmaları çözebiliyor (tüm aşağı akış birleşmeleri harika çalışıyor)
  • Özellik dalınızın asla çok eski olmamasını sağlamak için sık sık ve rutin olarak geliştirmeden bir araya gelmek
  • Özelliklerinizin 1-3 gün içinde yapılabilecek kadar küçük olduğundan emin olun.

Bu gibi değişikliklerle, çatışma olasılığını büyük ölçüde en aza indirebilirsiniz. Onları asla tamamen ortadan kaldıramazsınız.

97
Berin Loritsch

Muhtemelen teklif eksik:

İyi kodlayıcıların birleşme çatışmalarıyla uğraşmak zorunda kalmaz ...
... çünkü iyi kodlayıcılar İtme kuvveti.

Cidden, birleşme çatışmalarından kaçınmanın tek yolu tek başına çalışmaktır (ve bu bile yardımcı olmuyor; kişisel projelerde kendimle birleşme çatışmaları yaşadım). Bununla birlikte, deneyimli geliştiriciler işe alan bir şirkette, birleşme çatışmalarının acısını azaltan üç faktör vardır:

  1. Takım içinde mükemmel iletişim.

    Yani, iş arkadaşlarınızın ne üzerinde çalıştığını biliyorsunuz ve ne yaptığınızı biliyorlar. Bu nedenle, ekibinizden birinin üzerinde çalıştığı bir alanı muhtemelen değiştirdiğinizde, sorarsınız (ya da söylersiniz). Bu şekilde, acı verici bir taahhüt riskini çok azaltırsınız.

    Bu özellikle, kod tabanının büyük bir bölümünü önemli ölçüde etkileyebilecek veya birleştirilmesi acı verici değişiklikler yapan yeniden düzenleme görevlerine uygulanır. İş arkadaşınız bu değişkenin kullanıldığı bir özellik uygularken, her yerde belirli bir değişkenin türünü değiştirdiğinizi varsayalım. Sadece ağrılı bir birleşme çatışması yaşama riski değil, aynı zamanda birleştirme sırasında yapıyı kırma riski de vardır.

  2. Harika mimari.

    4K-LOC dosyalarıyla eski bir kod tabanı üzerinde çalışıyorsanız ve düzinelerce dosyayı değiştirmek için herhangi bir temel değişikliğe ihtiyacınız varsa, her değişiklikte birleştirme çakışması yaşamanız olasılığı vardır.

    Öte yandan, mimari yeterince iyi olduğunda, birleştirme çatışması olma riskini iki duruma düşürürsünüz: (1) bir arabirimi değiştirdiğiniz veya (2) iki iş arkadaşının uygulamanın aynı kısmını değiştirdiği . İlk durumda, ağrılı birleşme riskini daha da azaltarak iletişim kurarsınız. İkinci durumda, birleştirme işlemini tamamen kaldırarak çift programlama yaparsınız.

  3. Diğer takımlarla uygun arayüz.

    Bazen farklı takımlar arasında birleşme çatışmaları olur. Bir ekibin bir modülü değiştirirken başka bir ekibin bu modülü kullanan kodu değiştirdiğini varsayalım.

    Deneyimli geliştiriciler, sistemin ayrı parçalarını daha teknik olarak bağımsız hale getirecek SOA gibi uygun arayüzleri benimseme eğiliminde olacaklardır. Dahası, başka birinin kodunu doğrudan değiştirmekten kaçınmak için Push talepleri gibi belirli uygulamalara daha fazla güveneceklerdir.

    Bu aslında ilk iki noktadır, ancak çapraz takımlar: daha iyi iletişim kurarsınız ve parçaların daha karışık olmasını sağlarsınız.

27
Arseni Mourzenko

Bir meslektaşım, birleşme çatışmalarıyla uğraşmak zorunda olmayan bir geliştiriciye koştu.

Bazı değişiklikler yaptı, birleştirdi ve birkaç gün sonra değişiklikler gitti. Başka birisinin (farklı bir kıtada) birleştirme yerine dosyaların yerini aldığını öğrendi.

Değişiklikleri geri koydu, hafifçe değiştirdi - ve birkaç gün sonra değişiklikler tekrar gitti.

İşte o zaman, diğer takımın menajeriyle uzun bir konuşma yapan, fiziksel şiddete yönelik tehditleri içerebilecek veya içermeyebilecek olan ve diğer takımın menajeri görünüşe göre geliştiriciyle uzun bir konuşma yaptı. soru ve davranış durdu.

Bununla birlikte, deneyimli geliştiriciler bazı birleşme çatışmalarından kaçınabilir.

  1. Bir dosyayı yeniden adlandırdığınızda, dosyayı yeniden adlandırmanın (ve bunun içerdiği açıklamaların veya proje dosyalarının değiştirilmesi gibi bunun neden olduğu değişikliklerin) kesinlikle tek değişiklik olduğu bir birleştirme yapın.

  2. Herkesin editör ayarlarının aynı olduğundan emin olun, böylece sadece koda bakarak değişiklik oluşturmazsınız.

  3. İki kişi kodu değiştirirse birleştirme çakışmaları alırsınız aynı yerde. Bir dosyaya eklerseniz, sonunda eklemeyin, ancak mantıklı olarak doğru yere ekleyin. Bu şekilde başka bir geliştirici aynı şeyi yaparsa, birleştirme çakışmaları çok daha az olasıdır.

  4. Ortak kod tabanını zaman zaman şubenizde birleştirin, böylece hiçbir zaman çok birleştirme çakışması olmaz. Bir çatışma kolaydır, bir birleştirme işleminde 10 sorun vardır.

  5. Şubenizden ortak kod tabanına birleştirme asla çakışmalara neden olmalıdır. Bunun nedeni, birleştirmeyi denemeden hemen önce (4) yaptığınız için, birleştirmenin kodunuzu herhangi bir değişiklik yapmadan alması gerekir.

Sadece fark ettim: Evet, doğru, iyi geliştiricilerin hiçbir zaman şubelerinden ortak kod tabanına birleştirilen birleşme çatışmaları olmadı. Çünkü herhangi bir birleşme çatışması daha önce ele alınmıştı.

21
gnasher729

Diğer cevapların açıkladığı gibi, birleşme çatışmaları deneyim veya beceri ne olursa olsun meydana gelir ve beceri eksikliğinden kaynaklanan bir tür zayıflık olduklarını iddia eden bir atasözü saçmadır.

Diğer cevaplar, yetenekli geliştiricilerin biçimlendirme kaosunu sık sık birleştirmeye kadar daha iyi takım koordinasyonuna kadar birleştirme çatışmalarını daha az olası hale getirmeyi öğrenmenin yollarını kaydetti, ancak daha geniş konsepte doğru bir gerçek olduğunu düşünüyorum: yetenekli geliştiriciler daha iyi olabilir meydana geldiğinde birleşme çatışmalarıyla başa çıkmak.

Birleştirme çakışmalarını çözmek zordur. Çatışmaları bulmalı, çatışma işaretleyicilerini anlamalı, kodun bağlamını göz önünde bulundurarak her iki tarafta neyin değiştiğini bulmalısınız (muhtemelen biçimlendirme gibi zor noktalarla ilgili), belki de birleştirme işleminin her iki tarafından da bireysel taahhütlere bakın orijinal amacı anlayın, çatışmayı çözün, kod tabanındaki (veya API'ler veya arayüzler söz konusu olduğunda diğer depolarda bile) değişikliğin olası etkilerini ele alın, derleyin, test edin, taahhüt edin, vb. Bu işlem sırasında istediğinizi yapmak için sürüm kontrol sistemini edinin. Ve sonra daha karmaşık durumlar var: taşınan/silinen dosya ve dizinleri içeren çatışmalar; ikili dosyaları içeren çatışmalar; oluşturulan dosyaları içeren çakışmalar (Visual Studio ve Xcode yapılandırma dosyaları gibi şeyler dahil; çakışma basit olsa bile, onunla biraz deneyim kazanana kadar dosyanın kendisi bilinmeyecektir); birleşmenin diğer tarafındaki kişiyi bulup birlikte çözdüğünüzde yeterince kötü çatışmalar; her türlü eğlence.

Başa çıkmak için çok şey var. Biraz panik yaratabilir: bir şeyleri sarmak için heyecanlı bir yolculuk yapıyorsunuz ve aniden hata mesajlarıyla, dosyalarınızın ortasında garip ">>>>>>>" ve aniden başka bir yerden ortaya çıkan yabancı kod. Diğer herhangi bir programlama görevi gibi, deneyim de onunla daha verimli ve daha az acı verici bir şekilde başa çıkma becerilerini geliştirmeye yardımcı olabilir. Birleşme çatışmasıyla ilk karşılaştığınızda, kafa karıştırıcı bir çile, 500. kez daha rutin. Bu noktayla beraber:

  • Gereksinim duyduğunuz bilgileri almak ve istediğiniz değişiklikleri yapmak için sürüm kontrol sistemini kullanma becerisine sahipsiniz.
  • Çatışma formatını, farkları okuma ve birleştirmenin değişikliklerini görselleştirmeyi biliyorsunuz.
  • birleşmelere yardımcı olmak için açık kaynak veya ticari araçlar almış olabilir ve bunları etkili bir şekilde nasıl kullanacağınızı öğrenmiş olabilirsiniz. Bunlar son derece yardımcı olabilir, o kadar cesurca koyacağım: iyi araçlar birleştirme çatışmalarını çok daha az acı verici hale getirebilir .
  • Projelerinizde hangi tür çakışmaların tipik olduğunu (IDE yapılandırma dosyaları, dize dosyalarının altı, sık değişen diğer sıcak noktalar) bilirsiniz ve ya bunları önlemek için işlemleri düzenler ya da gerçekten hızlı bir şekilde çözme konusunda ustalaşırlar. "Oh, ikimiz de dosyanın altına yeni dizeler ekledik" gibi genel çakışmaların düzeltilmesi kolaylaşır.
  • Ne tür yeniden düzenleme görevlerinin ekibinizin geri kalanıyla çatışmaya yol açacağını tahmin edebilir ve ağrıyı azaltmak için koordine edebilirsiniz.
  • Ne zaman birleştirilmeyeceğini biliyorsun. Birleştirme girişiminde bulunur ve bir başkasının silmiş olduğu bir işleve bir parametre eklediğinizi keşfederseniz, stratejinizi çakışma çözümü sürecinin dışında durdurmak ve yeniden düşünmek daha iyi olabilir.
  • Ne zaman gerçek bir karmaşa yaptığınızı biliyorsunuz ve birleşmeyi yeniden başlatmak daha kolay olacak.
  • Temel kod tabanının, "birleştirmeyi" yaptığınız şey için adil bir açıklama yapmak için çok fazla değiştiğini biliyorsunuz, bu nedenle gerçekten yapmak istediğiniz değişiklikleri not edin, değişikliklerinizi atın ve yeni bir temiz HEAD ile yeniden başlayın. Örneğin, değişikliğiniz sadece yeni bir resim dosyası eklemekse ve bu arada birileri geldiğinde ve projenin tüm resimlerini sprite dönüştürdüyse, görevi artık farklı bir şekilde yapmak kadar bir araya gelmiyorsunuz, bu yüzden önceki çabanızı uçurun ve yeni bir şekilde yapın.

Bütün bunlarla, birleşme çatışmalarının çoğu rutin hale gelir, bu yüzden onlarla uğraşmak için daha az zaman ve çaba harcanır. Hala olurlar ve bazen önemli hayal kırıklığına neden olurlar, ancak genellikle çok daha az tahribat yaratırlar.

6
Zach Lipton

Bu birleşme çatışmalarının varlığı değil, ne kadar soruna neden olduklarıdır.

Deneyimsiz geliştiricilerle birleşme çatışmalarından kaynaklanan 'hasar' büyük bir sorun olarak görülüyor. İnsanlar bu 'büyük' ​​sorunlardan kaçınmak için çılgın kaynak kontrol şemaları icat ediyor hatta kaynak kontrolünü hep birlikte kullanmayı bırakıyor.

Ancak deneyimli bir ekiple, birleştirme çatışmaları neredeyse hiç soruna neden olmaz ve hızlı bir şekilde çözülür.

Bence buna katkıda bulunan iki temel farklılık var:

  1. Kaynak kontrolünü doğru kullanmak. Özellik dalları, çok sayıda küçük taahhüt, itmeden önce çekme, itmeden önce test etme, vb.

  2. Diğer insanların değişikliklerini anlama. Değişikliğinizle çakışan özellik ve kod değişikliklerini anlarsanız, ikisini birleştirmek basittir.

Stand-up'lardaki diğer görevlere dikkat edin, diğer insanlarla değişikliği nasıl uyguladıkları ve nerede çatışabileceğiniz hakkında konuşun. İşlerin önceden nasıl çalışması gerektiği konusunda anlaşın.

5
Ewan

Sürekli Entegrasyon .

CI'nin neden bir birleşme çatışması yaşamak için o daldaki değişikliklerin bir veya daha fazla ana değişiklikle çakışması gerektiğini düşünmesine yardımcı olduğunu anlamak için:

             A  B  C
master    *--*--*--*--*
           \         /
feature-x   *--------

Şube ne kadar uzun süre master için daha fazla değişiklik yapılırsa ve bu nedenle bu değişikliklerden birinin çatışmaya neden olma şansı o kadar artar (şube değişikliği çok küçük olsa bile):

             A  B  C  D  E  F  G  H
master    *--*--*--*--*--*--*--*--*--*
           \                        /
feature-x   *-----------------------

Herhangi bir 2 değişikliğin çatışması olasılığını azaltmak için yapabileceğimiz çeşitli şeyler vardır (yeniden biçimlendirmeden kaçınmak veya aynı alanda çalışan birden fazla geliştiriciyi önlemek için işi dikkatlice organize etmek gibi), ancak en basit yaklaşım, değişiklikleri daha hızlı bir şekilde birleştirmek, azaltmaktır. master'da yapılan değişikliklerin sayısı ve daha sonra çatışma olasılığı:

             A     B  C
master    *--*--*--*--*--*
           \   /    \   /
feature-x   *--      *--

CI'yi düzgün bir şekilde uyguluyorsanız, herkes günde birkaç kez paylaşılan bir şubeye , yani birkaç saatte bir taahhütte bulunmalıdır. Bu, çelişkili değişiklikler değil, çoğu zaman ustada herhangi bir değişiklik olmayacak kadar hızlıdır. Daha da iyisi, bir çatışma görseniz bile değişikliklerinizin küçük olacağı ve böylece çatışmanın çözülmesinin nispeten basit olması gerekir - en kötü senaryoda (değişikliğinizi tamamen atmanız ve yeniden uygulamanız gereken yerlerde) çoğu birkaç saat çalışır.


Yorumlarda geliştiricilerin ustalık yerine from ustası düzenli olarak birleştirmeleri gerektiği önerildi, ki bu kesinlikle yardımcı oluyor, ancak sürekli entegrasyon kadar değil. Örneğin, aşağıdaki grafikte her bir master (A, B ve C) taahhüdü, toplam 9 potansiyel çatışma için şubedeki herhangi bir taahhütle (X, Y veya Z) çakışma şansına sahiptir. Sonunda bir kez ustayla birleşmek, 9 potansiyel çatışmanın da aynı anda çözülmesi gerektiği anlamına gelir:

             A  B  C
master    *--*--*--*--*
           \         /
feature     *--*--*--
            X  Y  Z

Bunun yerine master'daki her değişiklikten sonra master'dan özellik şubemize birleşirsek:

             A     B     C
master    *--*-----*-----*---*
           \  \     \     \ /
feature     *--*--*--*--*--*
            X     Y     Z

O zaman her birleştiğimizde aşağıdaki çatışmalarla başa çıkmamız gerekir:

  • İlk birleştirmede A ve X taahhütleri arasındaki çatışmaları çözmeliyiz
  • İkinci birleşmede B ve X, B ve Y arasındaki çatışmaları çözüyoruz
  • Son birleştirmede C ve X, C ve Y, C ve Z arasındaki çatışmaları çözüyoruz

Ancak A ve Y arasındaki çatışmaları çözmemize gerek olmadığına dikkat edin, çünkü Y değişikliği yapılmadan önce A değişikliği özellik branşımızda birleştirildi. Toplamda, ustadan düzenli olarak birleşerek 9 potansiyel birleştirme çatışmasından 3'ünden kaçınmayı başardık.

Ayrıca, her birleştiğimizde potansiyel çatışmaların sayısı arttığına dikkat edin - özellik dalı ne kadar uzun süre mevcutsa, master üzerinde daha fazla değişiklik (ve dolayısıyla potansiyel çatışmalar) yapılacaktır, ancak buradaki gerçek katil, özellik dalında yaptığımız her değişikliğin her birleştiğimizde potansiyel çatışmaların sayısı üzerinde çarpma etkisi vardır.

Şimdi, eğer CI uygularsak neler olabileceğini düşünelim:

             A     B     C
master    *--*--*--*--*--*--*
           \   / \   / \   /
feature     *--   *--   *--
            X     Y     Z

Bu kez aşağıdaki birleşme çatışmalarıyla uğraşmak zorunda kaldık:

  • X değişikliğini ustayla birleştirirken, A ve X arasındaki çatışmaları çözmek zorunda kaldık
  • Y değişikliğini birleştirirken, X ve V arasındaki çatışmaları çözmek zorunda kaldık
  • Z'yi birleştirirken, Z ve C arasındaki çatışmaları çözmek zorunda kaldık

Daha önce olduğu gibi, A ve Y arasındaki herhangi bir çatışmayı çözmemize gerek yoktu, çünkü A değişikliği, Y değişikliğini yapmadan önce özellik şubemize birleştirildi, ancak bu sefer X ve B, X ve C değişikliklerini birleştirmemize gerek yoktu. veya Y ve C, 9 potansiyel çatışmadan 6'sından kaçınıyor.

Düzenli olarak master ile birleştirme hakkında daha fazla bilgi/rehberlik için bu soruya bakın:

“Sık sık” birleştirmek veya yalnızca tamamlandıktan sonra özellik dallarında büyük bir birleşim yapmak daha mı iyidir?

1
Justin

"Programcılar her zaman hata yapar her zaman " --- John Carmack

"Ben bir 'rockstar' geliştiricisiyim" veya "İyi kodlayıcıların birleşme anlaşmazlıklarıyla uğraşmak zorunda değil ..." gibi iddialarda bulunanlar, genel yazılım geliştirme topluluğunda bol görünen pozlardan daha sık değildir. ve bu şekilde göz ardı edilmelidir.

Üretimde bulunacak yazılımları kendinizin dışında oluşturmak önemsiz bir mesele değildir. Hatalar yapacaksınız ... ve birlikte çalıştığınız insanlar genellikle hatalar yapar. Herhangi birinin mühendislik yeterliliğinin bir değerlendirmesini, birleşme çatışmalarıyla uğraşmak zorunda kalıp kalmayacağı yüzünde saçmalıktır.

0
user405887

Kimin aklınızda "iyi kodlayıcı" kavramının belirli bir fikri olduğunu söyleyen, muhtemelen şöyle:

  • İyi Kodlayıcı tek başına tasarladığı bir Büyük Program üzerinde tek başına çalışır.
  • Programın çatalları veya serbest bırakma dalları veya herhangi bir türü yoktur ve bu nedenle çatışma yaratan hiçbir yeniden bastırma faaliyeti yoktur.
  • Programın eski sürümlerinde hatalar bulunduğunda, kullanıcılar ya mevcut taban çizgisine ya da başka bir şekilde aşağı doğru paket koruyucuları mevcut taban çizgisinden gerekli düzeltmeleri geri alırlar (bu nedenle Good Coder söz konusu çakışmaları asla görmez).
  • Bazı yabancıların Büyük Program için bir düzeltme veya geliştirme sağladığı nadir durumlarda, mevcut geliştirme başlığına temiz bir şekilde uygulanan bir yama sağlamaları gerekir, böylece İyi Kodlayıcı çatışma çözümlemesi içeren herhangi bir ileri taşıma çabasından korunur.
  • Son olarak, Good Coder taahhütlerinin sırasını asla değiştirmez (git'in etkileşimli rebaseinde olduğu gibi).
0
Kaz