Svn'deki birleşmeler arasında git veya mercurial'a göre bir fark var mı?


12

Anladığım kadarıyla SVN 'Şubesi kolay. Birleşmesi zor '. Neden? Birleştirme şekilleri arasında bir fark var mı?

git  svn  mercurial  dvcs 

Yanıtlar:


21

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

    • en büyük ortak ata versiyonu
    • tek dalda sürüm
    • diğer daldaki sürüm

    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 mergeSize bir ton çatışma çıkarırsa , iş arkadaşınızdan sizden istemesini isteyebilirsiniz hg pullve 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.


4
mükemmel cevap! Eğer yapabilirsem iki kez vekalet ederdim. SO içinde cevap için :) Ben de SVN kitap ait olduğunu eklemek istiyorum açıkça itiraf o "Subversion'ın birleştirme izleme özelliği son derece karmaşık iç uygulanmasını var ..." Tek başına bu özellik güvenilmez olduğunu oldukça iyi bir göstergesidir -
tatarcık

2
... ve bu son derece karmaşık bir uygulamada bile, ortak ataları basit ama hiçbir durumda doğru bir şekilde anlayamazsınız.
Jan Hudec

Gecikmeli birleşmeler hakkında - anlamayın - iş arkadaşım SVN ile / kasaya güncelleyebilir ve daha sonra şubemden birleştirebilir.
Gill Bates

@GillBates: SVN'de çalışırken, işiniz için bir şube başlatmadığınız bir durumdan bahsediyorum trunk. Bir DVCS ile paylaşmadan işlem yapabilirsiniz, ancak SVN'de svn commitaynı 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! :-)
Martin Geisler

6

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:

  • Birden fazla kafanız olabilir ve yine de bunlardan birini yapabilirsiniz; yıkımdan farklı olarak, tekrar taahhütte bulunmadan önce çekme, güncelleme ve birleştirme işlemlerini birleştirmeniz gerekmez - çoklu kafa birleştirmeyi seçene kadar bu şekilde kalır
  • Dizinler özel olarak ele alınmaz; bunun yerine, yol sadece büyük bir dosya adı olarak kabul edilir ve tüm dizinlerinizin her zaman aynı revizyonda olması gerekir. Bu, bir projenin alt klasörlerinin farklı revizyonlarda olduğu subversion voodoo'yu yapamayacağınız anlamına gelir, ancak aynı zamanda çalışan kopyanın yönetilemeyen büyük bir kırık karmaşaya dönüşme olasılığı daha düşüktür ve daha ilginç bir şekilde bir silme, bir silme olarak temsil edilmez -ve-add (geriye dönük meta veriler için olmasaydı tamamen svn'de kırılır), ama sadece bir yeniden adlandırma olarak; bir dosyayı taşırsanız, tüm geçmişi korunur; birleştirme, taşındıktan sonra başka bir dalda aynı dosyanın taşınmamış bir sürümünde yapılan taşınan dosyaya değişiklikler uygulayabilir
  • Çoğu zaman, aslında dallamanıza bile gerek yoktur : bunun yerine, tüm depoyu klonlarsınız. Klonlama ucuzdur, özellikle de aynı dosya sisteminde yapılırsa ve klondan kurtulmak istediğinize karar verirseniz, içinde bulunduğu dizini silersiniz ve işte budur. Bunun için hg veya git kullanmanıza bile gerek yok.
  • Neleri birleştirebileceğiniz konusunda (varsa) birkaç kısıtlama vardır. Aynı deponun altı klonuna sahip olabilir ve A'dan B'ye, sonra C'den B'ye, sonra B'den D'ye, sonra C'den D'ye, B geri birleştirebilir (veya daha doğrusu itme veya çekme; A, D'den E'ye, istediğiniz zaman ve istediğiniz sıklıkta.
  • Birleştirmeyi, birleştirmek istediğiniz depolardan birini klonlayıp diğerinden çekerek test edebilirsiniz. İstediğinizi yaparsa, gerçek hedefe geri itebilirsiniz, eğer yapmazsa, klonu atar ve yeniden başlarsınız.

2
Ben bazı düzeltmeler ve cevap ekler: 1. SVN revizyonları havuz başına global , revizyon bir süre içinde repo tüm dosyaları temsil 2. Birleştirme teknolojisi temelde SVN ve DVCS yaygın - birleştirme dosyaları sadece değişti ise Aynı şekilde , birleştirme SVN ve DVCS için aynı miktarda çakışma yaratacaktır - tüm SCM'ler mantıksal bir blok değil, hala dize düzeyinde çalışır 3. SVN'deki büyük taahhütler mimari zayıflıktan kaynaklanmaz, ancak kullanıcılar genellikle tembel aptallardır. - temel kalıpları görmezden gelirler. / Dev / beyin ve / dev / eller çalışıyorsa, birleştirme SVN'de çalışır
Lazy Badger

2
Bölüm 2: DVCS'de akıllı birleştirme çoğunlukla , Subversion'ın aksine, dosyaların yeniden adlandırılması | SVN'lerin hareketlerini izler ve yönetir, bu nedenle - dosyayı işleyen herhangi bir işlem, bir tarafta değişti ve yeniden adlandırıldı ikincisi başarısız olur. Dallar ve klonlama ile dallanma, aynı yaşam haklarına sahip farklı dallanma stratejileridir, bunlar "... bağlıdır ..."
Lazy Badger

@LazyBadger: Au contraire. Subversion yapar o birleştirmede yeniden adlandırma başa çıkıyor kısmen sahte çatışmaları neden iz hamle / yeniden adlandırmalar, basitçe arabası ve kısmen zor veya doğru işlemek için imkansız köşe durumlar vardır çünkü. Daha sonra git gelmez tasarımdan (ve cıva kopyaladı) neden değil yeniden adlandırmaları izlemek ve birleştirirken bunları tahmin eder. İçeriği hala birleştirilecek kadar benzer ise (bu, ihtiyacınız olan zamandır) iyi çalışır ve aptalca şeyler yapmaz.
Jan Hudec

@JanHudec - üzgünüm, SVN tutamacı hareket etmiyor | atomik bir eylemde yeniden adlandırır (DVCS yolu - "yeniden adlandır"), ancak "delete + ..." olarak DVCS'de gerçekleşmeyen ağaç çakışmaları üretir ( gerçek yeniden adlandırma) ). Mercurial parça açıkça yeniden adlandırılır ( hg mvveya 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.
Tembel Porsuk

5
Şimdi oldukça teknik oluyor :-) Yeniden adlandırma yerine Subversion ve Mercurial parça kopyaları . Her iki sistem bunu tek bir atomik işlem rename a bolarak izler copy a b; remove ave 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.
Martin Geisler
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.