Anladığım kadarıyla SVN 'Şubesi kolay. Birleşmesi zor '. Neden? Birleştirme şekilleri arasında bir fark var mı?
Anladığım kadarıyla SVN 'Şubesi kolay. Birleşmesi zor '. Neden? Birleştirme şekilleri arasında bir fark var mı?
Yanıtlar:
Mercurial'ın (ve Git'in) sorunsuz bir şekilde birleştiği ve Subversion'ın sahte bir çatışma ile karşılaştığı çok somut bir durum için lütfen Stack Overflow cevabım bakın . Durum, bazı dosyaları yeniden adlandırdığınız bir dalda yapılan basit bir yeniden düzenleme işlemidir.
Tdammers cevabı ile ilgili olarak, orada bir takım yanlış anlaşılmalar var:
Subversion, Mercurial ve Git projenin havuz genelindeki anlık görüntülerini izler. Onlara sürümler , revizyonlar veya değişiklik setleri denirse fark etmez. Hepsi mantıksal olarak bir dizi dosyanın atomik anlık görüntüleri.
Birleştirme söz konusu olduğunda taahhütlerinizin boyutu fark etmez . Her üç sistem de standart üç yollu birleştirme algoritması ile birleşir ve bu algoritmaya girişler
O önemli değil iki şube versiyonları nasıl yaratıldığını. Ata sürümünden bu yana 1000 küçük taahhüt kullanabilir veya 1 taahhüt kullanmış olabilirsiniz. Önemli olan dosyaların son sürümüdür. (Evet, bu şaşırtıcı! Evet, birçok DVCS kılavuzu bunu korkunç bir şekilde yanlış anlıyor.)
Ayrıca farklılıklar hakkında bazı iyi noktalar ortaya koyuyor:
Subversion'da bir araya gelebileceğiniz “voodoo” vardır /trunk
, diyelim ki /branches/foo
. Mercurial ve Git bu modeli kullanmaz - bunun yerine dallar doğrudan geçmişte modellenir. Bu nedenle tarih , doğrusal olmak yerine yönlendirilmiş bir asiklik grafik haline gelir . Bu, Subversion tarafından kullanılan modelden çok daha basit bir modeldir ve bu, birkaç köşe vakasını keser.
Bir birleştirmeyi kolayca geciktirebilir, hatta başkasının işlemesine izin verebilirsiniz . hg merge
Size bir ton çatışma çıkarırsa , iş arkadaşınızdan sizden istemesini isteyebilirsiniz hg pull
ve o da aynı duruma sahiptir. Böylece hg merge
çatışmaları çözmede sizden daha iyi olabilir ve belki de daha iyidir.
Taahhüt yapmadan önce güncellemeniz gereken Subversion ile bu çok zordur . Sunucudaki değişiklikleri görmezden gelemez ve kendi anonim dalınızda çalışmaya devam edemezsiniz. Genel olarak, Subversion güçleri bir uğraşmak kirli çalışma kopyası zaman svn update
. Değişikliklerinizi güvenli bir yerde saklamadığınız için bu biraz risklidir. Git ve Mercurial önce taahhütte bulunmanıza, ardından gerektiğinde güncellemenize ve birleştirmenize izin verir.
Git ve Mercurial'ın birleşmede asıl neden Subversion'dan daha iyi bir uygulama meselesidir. Subversion'ın doğru cevabın ne olduğu açık olsa bile, başa çıkamayacağı yeniden adlandırma çatışmaları var. Mercurial ve Git bunları kolayca halleder. Ancak Subversion'ın bunlarla da başa çıkamamasının bir nedeni yok - merkezileştirmek kesinlikle sebep değil.
trunk
. Bir DVCS ile paylaşmadan işlem yapabilirsiniz, ancak SVN'de svn commit
aynı dalda çalışan diğerlerini doğrudan etkileyeceksiniz. İkimiz SVN'de bir şube üzerinde çalışsak bile, çalışmanızla hemen birleşmek zorunda kalmadan işimi yapamam. Bu, taahhütleri biraz korkutucu hale getirir - bir sürüm kontrol sistemi için korkunç bir özelliktir! :-)
Temel sorun, bu sistemlerin sürümlenmiş bir dizin yapısını temsil etme biçiminde yatmaktadır.
Subversion'un tüm sistemin etrafında döndüğü temel konsepti, bir sürümün (ya da svn lingo'da "revizyon") konseptidir : belirli bir noktada bir dosyanın anlık görüntüsüdür. Tarih mükemmel derecede doğrusal olduğu sürece, her şey yolundadır, ancak iki bağımsız geliştirme çizgisinden değişiklikleri birleştirmeniz gerekiyorsa, svn her ikisinin de geçerli sürümlerini karşılaştırmalı ve ardından son paylaşılan sürüm arasında üç yönlü bir karşılaştırma yapmalıdır. ve iki kafa versiyonu. Kafalardan birinde değişmiş fakat diğerinde değişmeyen çizgiler kolayca çözülebilir; her iki kafada da tam olarak aynı şekilde sapan çizgiler daha zordur, ancak genellikle yapılabilir; farklı şekillerde sapan çizgiler svn "Bunu anlayamıyorum, insan, lütfen bunu benim için çöz" diyen şeylerdir.
Buna karşılık, sürümlerden ziyade git ve mercurial track değişiklik kümeleri . Deponun tamamı, her biri bir üst öğeye bağlı olarak, üst öğe kümesinin istediğiniz sayıda alt öğeye sahip olabileceği ve ağaç kökü boş bir dizini temsil eden bir değişiklik kümesi ağacıdır. Başka bir deyişle, git / hg "önce hiçbir şeyim yoktu, sonra bu yama uygulandı, sonra o yama vb." Diyor. İki geliştirme çizgisini birleştirmeniz gerektiğinde, git / hg sadece her bir kafanın neye benzediğini ve son ortak sürümün neye benzediğini bilmekle kalmaz, aynı zamanda geçişin nasıl gerçekleştiğini de bilir ve daha akıllı bir birleşmeye izin verir.
Bir DVCS'de birleştirmeyi kolaylaştıran bir başka şey, taahhüt ve güvenlik kavramlarını ayırmanın dolaylı bir sonucudur. itmeve aynı depodaki herhangi bir iki klon arasında herhangi bir zamanda her türlü çapraz birleştirmeye izin verme. SVN ile, insanlar genellikle ilgisiz değişikliklerle büyük değişiklik kümeleri yapma eğilimindedir, çünkü bir taahhüt aynı zamanda diğer tüm ekip üyelerini etkileyen merkezi depodaki bir güncellemedir; Eğer bozuk bir versiyona bağlanırsanız, herkes size kızacaktır. Çoğu kurulum ağa bağlı bir svn sunucusu içerdiğinden, işlem yapma ayrıca ağ üzerinden veri pompalamayı da içerir, bu da işlemenin iş akışına önemli bir gecikme getirdiği anlamına gelir (özellikle çalışma kopyanız eskiyse ve önce çekmeniz gerekir). Git ve mercurial ile, taahhüt yerel olarak gerçekleşir ve her ikisi de yerel dosya sistemlerini işlemede çok verimli olduğundan, genellikle anında biter. Sonuç olarak, insanlar (buna alıştıklarında) küçük artımlı değişiklikler yaparlar ve sonra çalışırlar, bir seferde bir düzine taahhütte bulunur. Daha sonra birleştirme zamanı geldiğinde, SCM daha ayrıntılı bilgiye sahiptir ve çatışmaları güvenli ve otomatik olarak çözmek için daha iyi bir iş yapabilir.
Ve sonra işleri daha da kolaylaştıran hoş detaylar var:
hg mv
veya hg addremove --similarity...
), Git sezgisel olarak kullanılır, ancak her ikisi de yeniden adlandırır . Birleştirilmiş dosyalarda 1 dize farkı bile ağaç çatışması alabilirsiniz ! Bazı Subversion özelliklerini tekrar öğrenmelisiniz, üzgünüm.
rename a b
olarak izler copy a b; remove a
ve her ikisi de yapar. Birleştirme davranışındaki fark, köşe kasalarının farklı şekilde işlenmesinden ve Mercurial ve Git'ten daha fazla birleştirmeye izin veren Subversion'dan kaynaklanır. Son olarak Git , birleştirme ve kayıt sırasında yeniden adlandırmalar algılar ; bunu Mercurial'a da eklemeyi düşünüyoruz.