Sürüm kontrol havuzunuzu nasıl düzenlersiniz?


108

Öncelikle şunu biliyorum: Şirket içi yazılım projeleri için bir Subversion deposunu nasıl düzenlersiniz? Sırada asıl soru şu: Ekibim depomuzu yeniden yapılandırıyor ve ben onu nasıl organize edeceğime dair ipuçları arıyorum. (Bu durumda SVN). İşte ortaya çıkardığımız şey. Bir depomuz, birden çok projemiz ve birden çok svn: harici çapraz referansımız var

\commonTools /*tools used in all projects. Referenced in each project with svn:externals*/
   \NUnit.v2.4.8
   \NCover.v.1.5.8
   \<other similar tools>
\commonFiles /*settings strong name keys etc.*/
   \ReSharper.settings
   \VisualStudio.settings
\trash /*each member of the team has trash for samples, experiments etc*/
   \user1
   \user2
\projects
   \Solution1 /*Single actual project (Visual Studio Solution)*/
      \trunk
         \src
             \Project1 /*Each sub-project resulting in single .dll or .exe*/
             \Project2
         \lib
         \tools
         \tests
         \Solution1.sln
      \tags
      \branches
   \Solution2
      \trunk
         \src
             \Project3 /*Each sub-project resulting in single .dll or .exe*/
             \Project1 /*Project1 from Solution1 references with svn:externals*/
         \lib
         \tools
         \tests
         \Solution2.sln
      \tags
      \branches

Kelime dağarcığını temizlemek için: Çözüm tek ürün anlamına gelir, Project bir Visual Studio Projesidir (tek bir .dll veya tek .exe ile sonuçlanır)

Depoyu bu şekilde düzenlemeyi planlıyoruz. Ana sorun, birden fazla Çözümümüz olması, ancak Projeleri Çözümler arasında paylaşmak istiyoruz. Bu paylaşılan Projeleri kendi Çözümlerine taşımanın gerçekten bir anlamı olmadığını düşündük ve bunun yerine svn: externals'ı Çözümler arasında Projeleri paylaşmak için kullanmaya karar verdik. Ayrıca, ortak araç setini ve 3. taraf kitaplıklarını depodaki tek bir yerde tutmak ve bunlara her Çözümde svn: externals ile başvurmak istiyoruz.

Bu düzen hakkında ne düşünüyorsunuz? Özellikle svn: harici kullanımı hakkında. İdeal bir çözüm değil, ancak tüm artıları ve eksileri göz önünde bulundurarak, düşünebildiğimizin en iyisi bu. Nasıl yapardın?


"Thrash" demek istediğinizden emin misiniz? Yoksa "çöp" mü?
ssc

Yanıtlar:


92

Aşağıdaki tavsiyelerime uyarsanız (yıllardır uyguluyorum), şunları yapabileceksiniz:

- Yapıyı proje kök dizininden aşağıya doğru koruduğunuz sürece, her projeyi kaynak denetiminde herhangi bir yere koyun

- minimum risk ve minimum hazırlık ile her projeyi herhangi bir makinede herhangi bir yere inşa edin

- ikili bağımlılıklarına (yerel "kütüphane" ve "çıktı" dizinleri) erişiminiz olduğu sürece her projeyi tamamen bağımsız olarak oluşturun

- bağımsız oldukları için herhangi bir proje kombinasyonu oluşturun ve bunlarla çalışın

- bağımsız olduklarından, tek bir projenin birden çok kopyasını / versiyonunu oluşturun ve bunlarla çalışın

- kaynak kontrol havuzunuzu oluşturulan dosyalar veya kitaplıklarla karıştırmaktan kaçının

Tavsiye ederim (işte sığır eti):

  1. .DLL, .EXE veya .JAR (Visual Studio ile varsayılan) gibi tek bir birincil teslim edilebilir ürün üretmek için her projeyi tanımlayın.

  2. Her projeyi tek bir köke sahip bir dizin ağacı olarak yapılandırın.

  3. Kök dizinindeki her proje için, bir IDE'ye YOK bağımlılık olmadan onu sıfırdan oluşturacak (ancak mümkünse IDE'de oluşturulmasını engellemeyin) otomatikleştirilmiş bir derleme komut dosyası oluşturun.

  4. Windows'ta nAnt for .NET projelerini veya işletim sisteminize, hedef platformunuza vb. Dayalı benzer bir şeyi düşünün.

  5. Her proje derleme betiğinin, tek bir yerel paylaşılan "kitaplık" dizininden harici (üçüncü taraf) bağımlılıklarına başvurmasını sağlayın, bu tür her ikili dosya TAMAMEN sürüm: %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  6. Her proje oluşturma komut dosyasının birincil teslim edilebilir olanı tek bir yerel paylaşılan "çıktı" dizininde yayınlamasını sağlayın: %DirOutputRoot%\ProjectA-9.10.11.12.dll, %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. Her proje derleme betiğinin, "kitaplık" ve "çıktı" dizinlerinde yapılandırılabilir ve tam sürümlü mutlak yollar (yukarıya bakın) aracılığıyla bağımlılıklarına başvurmasını sağlayın VE BAŞKA YERDE OLMAYACAKTIR.

  8. ASLA bir projenin başka bir projeye veya içeriğinden herhangi birine doğrudan atıfta bulunmasına izin vermeyin - yalnızca "çıktı" dizinindeki birincil çıktılara referanslara izin verin (yukarıya bakın).

  9. Yapılandırılabilir ve tam sürümlü bir mutlak yol ile her proje derleme komut dosyasının gerekli derleme araçlarına başvurmasını sağlayın: %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  10. Proje kök dizinine bir mutlak yol akrabası tarafından her proje inşa komut referans kaynak içeriği olun: ${project.base.dir}/src, ${project.base.dir}/tst(sözdizimi inşa aracı göre değişir).

  11. HER ZAMAN, HER dosya veya dizine mutlak, yapılandırılabilir bir yol (yapılandırılabilir bir değişkenle belirtilen bir dizinde köklü) aracılığıyla başvurmak için bir proje oluşturma komut dosyası gerektirir: ${project.base.dir}/some/dirsveya ${env.Variable}/other/dir.

  12. Bir proje derleme betiğinin HİÇBİR ŞEYE .\some\dirs\hereveya gibi göreli bir yolla başvurmasına ASLA izin vermeyin ..\some\more\dirs, HER ZAMAN mutlak yollar kullanın.

  13. Bir proje derleme komut dosyasının, C:\some\dirs\hereveya gibi yapılandırılabilir bir kök dizini olmayan mutlak bir yolu kullanarak HERHANGİ BİR ŞEYE başvurmasına ASLA izin vermeyin \\server\share\more\stuff\there.

  14. Bir proje oluşturma komut dosyası tarafından başvurulan her yapılandırılabilir kök dizin için, bu başvurular için kullanılacak bir ortam değişkeni tanımlayın.

  15. Her makineyi yapılandırmak için oluşturmanız gereken ortam değişkenlerinin sayısını en aza indirmeye çalışın.

  16. Her makinede, gerekli ortam değişkenlerini tanımlayan bir kabuk komut dosyası oluşturun, bu, bu makineye özeldir (ve uygunsa muhtemelen o kullanıcıya özeldir).

  17. Makineye özgü yapılandırma kabuk komut dosyasını kaynak kontrolüne KOYMAYIN; bunun yerine, her proje için, proje kök dizinindeki komut dosyasının bir kopyasını şablon olarak işleyin.

  18. Ortam değişkenlerinin her birini kontrol etmesi için her proje oluşturma komut dosyasını GEREKTİRİN ve tanımlanmamışlarsa anlamlı bir mesajla iptal edin.

  19. Bağımlı derleme aracı yürütülebilir dosyalarının, harici kitaplık dosyalarının ve projeye bağımlı olarak teslim edilebilir dosyaların her birini denetlemek için her proje oluşturma betiğini GEREKTİRİN ve bu dosyalar yoksa anlamlı bir mesajla iptal edin.

  20. Üretilen HERHANGİ BİR dosyayı kaynak kontrolüne kaydetme eğilimine DİRENÇ - proje çıktıları yok, oluşturulan kaynak yok, oluşturulan belgeler yok, vb.

  21. Bir IDE kullanıyorsanız, yapabildiğiniz her türlü proje denetim dosyasını oluşturun ve bunları kaynak denetimine kaydetmeyin (bu, Visual Studio proje dosyalarını içerir).

  22. Geliştirici iş istasyonlarına kopyalanacak / yüklenecek ve makineler oluşturacak, tüm harici kitaplıkların ve araçların resmi bir kopyasını içeren bir sunucu kurun. Kaynak kontrol havuzunuzla birlikte yedekleyin.

  23. Herhangi bir geliştirme aracı YOK olan sürekli bir entegrasyon sunucusu (inşa makinesi) kurun.

  24. Harici kitaplıklarınızı ve çıktılarınızı yönetmek için Ivy gibi (Ant ile birlikte kullanılan) bir araç düşünün.

  25. Maven'i KULLANMAYIN - başlangıçta sizi mutlu edecek ve sonunda sizi ağlatacaktır.

Bunların hiçbirinin Subversion'a özgü olmadığını ve çoğunun herhangi bir işletim sistemi, donanım, platform, dil vb. Hedeflenen projeler için genel olduğunu unutmayın. Biraz işletim sistemi ve araca özgü sözdizimi kullandım, ancak yalnızca örnekleme için -İşletim sisteminize veya tercih ettiğiniz araca çevireceğinize güveniyorum.

Visual Studio çözümleriyle ilgili ek not: Bunları kaynak denetimine koymayın! Bu yaklaşımla bunlara hiç ihtiyacınız olmaz veya bunları oluşturabilirsiniz (tıpkı Visual Studio proje dosyaları gibi). Ancak, çözüm dosyalarını uygun gördükleri şekilde oluşturmaları / kullanmaları için (ancak kaynak kontrolüne teslim edilmemiş) tek tek geliştiricilere bırakmanın en iyi yol olduğunu düşünüyorum. Rob.slnMevcut projelerime başvurduğum iş istasyonumda bir dosya tutuyorum. Projelerim tamamen bağımsız olduğundan, istediğim zaman proje ekleyebilir / kaldırabilirim (bu, proje bazlı bağımlılık referansı olmadığı anlamına gelir).

Lütfen Subversion harici (veya diğer araçlarda benzerlerini) kullanmayın, bunlar bir anti-modeldir ve bu nedenle gereksizdir.

Sürekli entegrasyon uyguladığınızda veya sadece yayın sürecini otomatikleştirmek istediğinizde bile bunun için bir komut dosyası oluşturun. Tek bir kabuk komut dosyası oluşturun: proje adı (depoda listelendiği gibi) ve etiket adı parametrelerini alan, yapılandırılabilir bir kök dizin içinde geçici bir dizin oluşturan, verilen proje adı ve etiket adı için kaynağı kontrol eden ( Subversion durumunda uygun URL) bu geçici dizine, testler çalıştıran ve teslim edilebilir olanı paketleyen temiz bir yapı gerçekleştirir. Bu kabuk betiği herhangi bir proje üzerinde çalışmalı ve "derleme araçları" projenizin bir parçası olarak kaynak kontrolünde kontrol edilmelidir. Sürekli bütünleştirme sunucunuz bu komut dizisini proje oluşturmak için temel olarak kullanabilir veya hatta sağlayabilir (ancak yine de kendinizinkini isteyebilirsiniz).

@VonC: Derleme betiğiniz bozulduğunda "ant-abcdjar" yerine "ant.jar" yerine "ant.jar" ile çalışmak istemezsiniz çünkü bilmeden Ant'ın uyumsuz bir sürümüyle çalıştırdınız. Bu özellikle Ant 1.6.5 ve 1.7.0 arasında yaygındır. Genelleme yaparak, HER ZAMAN, platformunuz (Java ABCD) ve oluşturma aracınız (Ant EFGH) dahil, HER bileşenin hangi özel sürümünün kullanıldığını bilmek istersiniz. Aksi takdirde, sonunda bir hatayla karşılaşırsınız ve ilk BÜYÜK sorununuz, çeşitli bileşenlerinizin hangi sürümlerinin dahil olduğunu takip eder. Bu sorunu önceden çözmek daha iyidir.


6
Eleştirilecek pek çok nokta ... bunun evrensel bir tarif olmadığını söylemek yeterli ! Özellikle 5. ve 6. maddeler, proje büyük olduğunda ve üçüncü tarafların sayısı önemli olduğunda çok yanlıştır: Her zaman 'ant1.5.4.jar' veya ürün myProduct değil, 'ant.jar' ile çalışmak istersiniz. .exe, 1.3.exe değil
VonC

5
Yine de, konuyla ilgili engin deneyiminiz için geçerli olan ve çok iyi konuşan diğer birçok puan için +1.
VonC

3
Eleştirilerinizi duymak ve onlarla etkileşim kurmak isterim - her nokta büyük projelerle kötü deneyimleri çözmeye dayanmaktadır. Örneğin, hangi sürümlerin Xxx.jar ve Yyy.exe tarafından temsil edildiği konusunu ele almak, özellikle de tam anlamıyla bir düzine kopyaya başvurulduğunda.
Rob Williams

2
@Rob - 'Dışsallar karşıtı' temanız üzerinde biraz ayrıntı verebilir misiniz? Bunu burada bir soru olarak gündeme getirdim: stackoverflow.com/questions/338824/…
Ken

3
@Makis: Haklısınız, EĞER # 12 # 13 ile dengelenmemiş. Her proje içindeki bir dosya veya dizine yapılan her başvuru, yapılandırılabilir bir kök dizin değişkeniyle başlayan mutlak bir yol aracılığıyla yapılmalıdır, örneğin Ant'ta $ {basedir} /sub/dir/file.txt.
Rob Williams


3

Bizimki, gönderdiklerinizle neredeyse tamamen eşleşecek şekilde ayarladık. Genel formu kullanıyoruz:

\Project1
   \Development (for active dev - what you've called "Trunk", containing everything about a project)
   \Branches (For older, still-evolving supported branches of the code)
       \Version1
       \Version1.1
       \Version2
   \Documentation (For any accompanying documents that aren't version-specific

Örneğiniz kadar eksiksiz olmasa da bizim için işe yaradı ve işleri ayrı tutmamıza izin veriyor. Her kullanıcının bir "Thrash" klasörüne sahip olması fikrini seviyorum - şu anda bu tür projeler Kaynak denetiminde sona ermiyor ve her zaman olması gerektiğini hissettim.


3
Sürümler arasında değişmeyen belgeler için ayrı bir dizininiz olmasına şaşırdım ... Böyle bir ürün üzerinde çalışmaktan hiç zevk almadım! :)
ARKBAN

1

Neden hepsi tek bir depoda var? Neden her proje için ayrı bir depoya sahip değilsiniz ("Çözüm" demek istiyorum)?

En azından depo başına bir proje yaklaşımına alıştım. Depo yapınız bana aşırı karmaşık görünüyor.

Ve bu büyük depoya kaç tane proje koymayı planlıyorsunuz? 2? 3? 10? 100?

Ve bir projenin geliştirilmesini iptal ettiğinizde ne yaparsınız? İleride bulması zorlaşması için arşiv ağacından silin. Yoksa sonsuza kadar ortalıkta mı bırakacaksın? Veya bir projeyi tamamen başka bir sunucuya taşımak istediğinizde?

Peki tüm bu sürüm numaralarının karışıklığı ne olacak? Bir projenin sürüm numaraları 2, 10, 11, diğeri 1, 3, 4, 5, 6, 7, 8, 9, 12 ...

Belki aptalım ama depo başına bir proje seviyorum.


1. Bir depo bir şirket politikasıdır, bunu değiştiremezsiniz. 2. Yaklaşık düzine Çözümümüz olacak. 3. sürüm numaraları ile revizyonları mı kastediyorsunuz? Bu bizim için bir sorun değil.
Krzysztof Kozmic

İyi bir proje yapısı, özellikle bir veya daha fazla havuzla ilgili olarak depo yapısının geri kalanından habersiz olmalıdır. Lütfen ayrıntılı cevabıma bakın.
Rob Williams

1
Birçok (çoğu?) Kaynak kontrol aracında birden fazla depoya sahip olmanın, güvenliği uyguladığınızda olduğu gibi ÇOK pahalı olabileceğini lütfen unutmayın.
Rob Williams

0

Bence önerilen yapının ana dezavantajı, paylaşılan projelerin yalnızca eklendikleri ilk çözümle versiyonlanacak olmasıdır (svn: externals düşündüğümden daha meraklı değilse). Örneğin, Solution2'nin ilk sürümü için bir dal oluşturduğunuzda, Project1 Solution1'de yaşadığı için dallanmayacaktır. Bu şubeden daha sonra derlemeniz gerekirse (QFE sürümü), şube sırasında Project1 sürümü yerine Project1'in en son sürümünü kullanacaktır.

Bu nedenle, paylaşılan projeleri bir veya daha fazla paylaşılan çözüme (ve dolayısıyla yapınızdaki en üst düzey dizinlere) yerleştirmek ve ardından bunları herhangi bir çözümün her sürümüyle dallandırmak avantajlı olabilir .


Bir dereceye kadar haklısın. Ancak istersek referansı güncelleyebiliriz. Ve paylaşılan Projeleri kendi Çözümlerine koymak da pek mantıklı değil. Her ne kadar svn'den daha iyi bir çözüm bulmayı çok isterdim: her yerde harici.
Krzysztof Kozmic

"İstersek referansı güncelle" ile ne demek istiyorsun? Solution1'i dallandırmadan Project1'i nasıl dallara ayırabileceğinizi (Solution2'yi her daldırdığınızda arzu edilir gibi görünüyor) anlamıyorum.
C. Dragon 76

Lütfen ayrıntılı cevabıma bakın, özellikle Visual Studio çözümlerini kaynak denetimine KOYMAYIN.
Rob Williams

0

Göreli yol sorununa eklemek için:

Bunun bir sorun olduğundan emin değilim:
"Solution1" adlı dizinin altındaki Solution1 / trunk'ı kontrol edin, Solution2 için aynen: dalları temsil eden 'dizinlerin' amacı, bir çalışma alanına aktarıldıktan sonra görünür olmamaktır . Bu nedenle, 'Çözüm1' (aslında 'Çözüm1 / ana hat') ve 'Çözüm2' (Çözüm2 / gövde) arasında göreceli yollar mümkündür.


Bu çok kolay kırılır, lütfen detaylı cevabıma bakınız.
Rob Williams

0

RE: göreceli yol ve paylaşılan dosya sorunu -

Görünüşe göre bu svn'ye özgü, ancak bu bir sorun değil. Başka bir kişi daha önce ayrı depolardan bahsetti ve bu, keyfi başka projelere atıfta bulunan farklı projeleriniz olması durumunda muhtemelen düşünebileceğim en iyi çözümdür. Paylaşılan dosyanız yoksa, OP çözümü (ve diğerleri gibi) iyi çalışacaktır.

Halen bunun üzerinde çalışıyoruz ve var olmayan ya da zayıf sürüm kontrolünü kurmayı devraldığım için şu anda çözmem gereken 3 farklı çabam var (farklı istemciler).


Projelerin diğer projelere referans vermesi bir bakım kabusu yaratır çünkü bağımlılıklar katlanarak büyür ve referanslar ÇOK kırılgandır. Lütfen ayrıntılı cevabıma bakın.
Rob Williams

0

Benzer bir düzenim var, ancak bagajım, dallarım, etiketlerim tamamen en üstte. Yani: / trunk / main, / trunk / utils, / branch / release /, vb.

Bu, diğer sürüm kontrol sistemlerini denemek istediğimizde gerçekten kullanışlı oldu çünkü çeviri araçlarının çoğu, temel ders kitabı SVN düzeniyle en iyi şekilde çalıştı.

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.