Jak zorganizować repozytorium kontroli wersji?

Po pierwsze, wiem o tym: Jak zorganizowałbyś repozytorium Subversion dla projektów oprogramowania in house? Następnie pytanie: Mój zespół restrukturyzuje nasze repozytorium i szukam wskazówek, jak je zorganizować. (SVN w tym przypadku). Oto, co wymyśliliśmy. Mamy jedno repozytorium, wiele projektów i wiele odsyłaczy svn: externals

\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

Aby wyczyścić słownictwo: rozwiązanie oznacza pojedynczy produkt, projekt jest projektem Visual Studio (który powoduje w singlu .dll lub pojedyncze .exe)

W ten sposób planujemy rozłożyć repozytorium. Głównym problemem jest to, że mamy wiele rozwiązań, ale chcemy dzielić projekty między rozwiązania. Uznaliśmy, że nie ma sensu przenosić tych wspólnych projektów na ich własne rozwiązania, a zamiast tego zdecydowaliśmy się użyć svn:externals do dzielenia się projektami między rozwiązaniami. Chcemy również, aby wspólny zestaw narzędzi i biblioteki stron trzecich były w jednym miejscu w repozytorium, a one odwoływały się do nich w każdym z nich Rozwiązanie z svn: zewnętrzne.

Co sądzisz o tym układzie? Zwłaszcza o stosowaniu svn: zewnętrzne. Nie jest to idealne rozwiązanie, ale biorąc pod uwagę wszystkie plusy i minusy, to najlepsze, co mogliśmy wymyślić. Jak byś to zrobił?

Author: Krzysztof Kozmic, 2008-10-21

8 answers

Jeśli zastosujesz się do moich zaleceń poniżej( mam od lat), będziesz mógł:

-- umieść każdy projekt w dowolnym miejscu pod kontrolą źródła, o ile zachowasz strukturę z katalogu głównego projektu na dole

-- buduj każdy projekt w dowolnym miejscu na dowolnej maszynie, z minimalnym ryzykiem i minimalnym przygotowaniem

-- buduj każdy projekt całkowicie samodzielnie, o ile masz dostęp do jego binarnych zależności (lokalna "biblioteka" i " wyjście" katalogi)

-- buduj i pracuj z dowolną kombinacją projektów, ponieważ są one niezależne

-- tworzenie i praca z wieloma kopiami / wersjami jednego projektu, ponieważ są one niezależne

-- unikaj zaśmiecania repozytorium kontroli źródeł generowanymi plikami lub bibliotekami

Polecam (oto wołowina):

  1. Zdefiniuj każdy projekt, aby wyprodukować jeden podstawowy produkt, taki jak.DLL, .EXE, lub .JAR (domyślnie z Visual Studio).

  2. Struktura każdego projektu jako drzewa katalogów z jednym korzeniem.

  3. Utwórz automatyczny skrypt budowania dla każdego projektu w katalogu głównym, który zbuduje go od podstaw, bez zależności od IDE(ale nie uniemożliwiaj jego zbudowania w IDE, jeśli to możliwe).

  4. Rozważ nAnt dla projektów. NET w systemie Windows lub coś podobnego w oparciu o Twój system operacyjny, platformę docelową itp.

  5. Zbuduj każdy projekt skrypt odwołuje się do zewnętrznych (zewnętrznych) zależności z jednego lokalnego współdzielonego katalogu "biblioteka", z każdym takim binarnym w pełni identyfikowanym przez wersję: %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  6. Spraw, aby każdy skrypt budowania projektu publikował podstawowe dane dostarczane do jednego lokalnego współdzielonego katalogu" output": %DirOutputRoot%\ProjectA-9.10.11.12.dll, %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. Spraw, aby każdy skrypt budowania projektu odwoływał się do jego zależności za pomocą konfigurowalnych i w pełni wersjonowanych ścieżek absolutnych (patrz wyżej) w" bibliotece "i" wyjściu" katalogi, i nie gdzie indziej.

  8. Nigdy nie pozwól, aby projekt bezpośrednio odwoływał się do innego projektu lub jakiejkolwiek jego zawartości--Zezwalaj tylko na odniesienia do głównych rezultatów w katalogu "output" (patrz wyżej).

  9. Spraw, aby każdy skrypt budowania projektu odwoływał się do wymaganych narzędzi budowania za pomocą konfigurowalnej i w pełni wersjonowanej ścieżki absolutnej: %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  10. Aby każdy projekt build script reference source content by a absolute path related to katalog główny projektu: ${project.base.dir}/src, ${project.base.dir}/tst (składnia różni się w zależności od narzędzia budowania).

  11. Zawsze wymagaj skryptu budowania projektu, aby odwoływać się do każdego PLIKU lub katalogu za pomocą bezwzględnej, konfigurowalnej ścieżki (zakorzenionej w katalogu określonym przez konfigurowalną zmienną): ${project.base.dir}/some/dirs lub ${env.Variable}/other/dir.

  12. Nigdy nie zezwalaj skryptowi budowania projektu na odwoływanie się do czegokolwiek ze ścieżką względną, taką jak .\some\dirs\here lub ..\some\more\dirs , Zawsze używaj ścieżek bezwzględnych.

  13. Nigdy nie zezwalaj skrypt budowy projektu na odwołaj się do wszystkiego za pomocą ścieżki bezwzględnej, która nie ma konfigurowalnego katalogu głównego, takiego jak C:\some\dirs\here lub \\server\share\more\stuff\there.

  14. Dla każdego konfigurowalnego katalogu głównego, do którego odwołuje się skrypt budowania projektu, zdefiniuj zmienną środowiskową, która będzie używana dla tych odniesień.

  15. Spróbuj zminimalizować liczbę zmiennych środowiskowych, które musisz utworzyć, aby skonfigurować każdą maszynę.

  16. Na każdym komputerze Utwórz skrypt powłoki, który definiuje niezbędne zmienne środowiskowe, które są specyficzne dla tej Maszyny (i ewentualnie specyficzne dla tego użytkownika, jeśli dotyczy).

  17. Nie umieszczaj skryptu powłoki konfiguracyjnej specyficznej dla komputera w kontrolce źródłowej; zamiast tego, dla każdego projektu, Zatwierdź kopię skryptu w katalogu głównym projektu jako szablon.

  18. Wymagaj, aby każdy skrypt budowania projektu sprawdzał każdą ze zmiennych środowiskowych i przerywał z sensownym Komunikatem, jeśli nie są zdefiniowany.

  19. Wymagaj, aby każdy skrypt budowania projektu sprawdzał każdy z jego zależnych plików wykonywalnych narzędzia budowania, zewnętrznych plików bibliotek i zależnych plików dostarczalnych projektu i przerywał ze znaczącym Komunikatem, jeśli te pliki nie istnieją.

  20. Oprzyj się pokusie poddania wygenerowanych plików kontroli źródłowej-bez rezultatów projektu, bez wygenerowanych źródeł, bez wygenerowanych dokumentów itp.

  21. Jeśli używasz IDE, Wygeneruj dowolną kontrolę nad projektem pliki można, ale nie należy ich przypisywać do kontroli źródłowej (dotyczy to również plików projektu Visual Studio).

  22. Utwórz serwer z oficjalną kopią wszystkich zewnętrznych bibliotek i narzędzi, które będą kopiowane / instalowane na stacjach roboczych programistów i maszynach budowlanych. Wykonaj kopię zapasową wraz z repozytorium kontroli źródeł.

  23. Stwórz serwer ciągłej integracji (maszynę do budowania) bez żadnych narzędzi programistycznych.

  24. Rozważ narzędzie do zarządzanie zewnętrznymi bibliotekami i produktami, takimi jak Ivy (używane z Ant).

  25. Nie używaj Mavena-początkowo sprawi, że będziesz szczęśliwy, a w końcu sprawi, że będziesz płakać.

Zauważ, że nic z tego nie jest specyficzne dla Subversion, a większość z nich jest ogólna dla projektów ukierunkowanych na dowolny system operacyjny, sprzęt, platformę, język itp. Użyłem trochę składni specyficznej dla systemu operacyjnego i narzędzi, ale tylko dla ilustracji-ufam, że przetłumaczysz na swój system operacyjny lub narzędzie wybór.

Dodatkowa uwaga dotycząca rozwiązań Visual Studio: nie poddawać ich kontroli źródłowej! Dzięki takiemu podejściu w ogóle ich nie potrzebujesz lub możesz je generować (tak jak pliki projektów Visual Studio). Jednak uważam, że najlepiej pozostawić pliki rozwiązań poszczególnym programistom, aby tworzyli / używali według własnego uznania(ale nie sprawdzali w kontroli źródła). Przechowuję plik Rob.sln na mojej stacji roboczej, z którego odwołuję się do moich obecnych projektów. Ponieważ moje projekty są samodzielne, może dodawać / usuwać projekty do woli(oznacza to, że nie ma odniesień do zależności opartych na projekcie).

Proszę nie używać zewnętrznych elementów Subversion (lub podobnych w innych narzędziach), są one anty-wzorcem i dlatego niepotrzebne.

Gdy zaimplementujesz ciągłą integrację, lub nawet gdy po prostu chcesz zautomatyzować proces wydawania, utwórz dla niej skrypt. Tworzy pojedynczy skrypt powłoki, który: pobiera parametry nazwy projektu (wymienione w repozytorium) i nazwy znacznika, tworzy tymczasowy katalog w konfigurowalnym katalogu głównym, sprawdza źródło dla podanej nazwy projektu i nazwy znacznika (konstruując odpowiedni adres URL w przypadku Subversion) do tego katalogu tymczasowego, wykonuje czystą kompilację, która uruchamia testy i pakiety dostarczane. Ten skrypt powłoki powinien działać na każdym projekcie i powinien być sprawdzany pod kontrolą źródłową jako część projektu "narzędzia do budowania". Twój serwer ciągłej integracji może użyć tego skryptu jako podstawy dla projektów budowlanych lub może nawet go dostarczyć (ale nadal możesz chcieć swojego).

@VonC: nie chcesz przez cały czas pracować z " ant.słoik " zamiast "ant-a.b.c.d.jar" po tym, jak zostaniesz spalony, gdy twój skrypt build pęknie, ponieważ nieświadomie uruchomiłeś go z niezgodną wersją Ant. Jest to szczególnie powszechne między Ant 1.6.5 i 1.7.0. Uogólniając, zawsze chcesz wiedzieć, jaka konkretna wersja każdego komponentu jest używana, w tym twoja platforma (Java A. B. C. D) i twoje narzędzie do budowania (Ant E. F. G. H). W przeciwnym razie w końcu napotkasz błąd, a twoim pierwszym dużym problemem będzie śledzenie, jakie wersje różnych komponentów są zaangażowane. Po prostu lepiej jest rozwiązać ten problem z góry.

 93
Author: Rob Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:58:38

Uważam, że pragmatyczna Kontrola wersji za pomocą Subversion ma wszystko, czego potrzebujesz, aby uporządkować swoje repozytorium.

 3
Author: Fabio Gomes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 18:21:30

Ustawiliśmy nasze prawie dokładnie tak, aby pasowały do tego, co opublikowałeś. Używamy formy ogólnej:

\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

Chociaż przypuszczam, że nie tak kompletny jak twój przykład, to działa dobrze dla nas i pozwala nam zachować rzeczy osobno. Podoba mi się pomysł, aby każdy użytkownik miał folder "Thrash" - obecnie tego typu projekty nie kończą się kontrolą źródeł i zawsze uważałem, że powinny.

 3
Author: SqlRyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 18:32:22

Po co mieć wszystko w jednym repozytorium? Dlaczego po prostu nie mieć osobnego repozytorium dla każdego projektu (mam na myśli "rozwiązanie")?

Cóż, przynajmniej przyzwyczaiłem się do podejścia do jednego projektu na repozytorium. Twoja struktura repozytorium wydaje mi się zbyt skomplikowana.

A ile projektów planujesz umieścić w tym jednym dużym repozytorium? 2? 3? 10? 100?

A co zrobić, gdy anulujesz rozwój jednego projektu? Wystarczy usunąć go z drzewa repozytorium, aby stało się trudne do Znajdź w przyszłości. Czy zostawić to na zawsze? A może chcesz przenieść jeden projekt na inny serwer?

A co z bałaganem tych wszystkich numerów wersji? Numery wersji jednego projektu idą jak 2, 10, 11, podczas gdy drugi idzie jak 1, 3, 4, 5, 6, 7, 8, 9, 12...

Może jestem głupi, ale lubię jeden projekt na repozytorium.

 1
Author: Rene Saarsoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 18:57:23

Myślę, że główną wadą proponowanej struktury jest to, że wspólne projekty będą wersjonowane tylko z pierwszym rozwiązaniem, do którego zostały dodane (chyba, że svn: externals jest bardziej fantazyjne niż sobie wyobrażam). Na przykład, gdy utworzysz gałąź dla pierwszego wydania Solution2, Project1 nie będzie rozgałęziony, ponieważ mieszka w Solution1. Jeśli chcesz zbudować z tej gałęzi w późniejszym czasie (wydanie QFE), będzie ona używać najnowszej wersji Project1 zamiast wersji Project1 w tym czasie oddziału.

Z tego powodu korzystne może być umieszczenie współdzielonych projektów w jednym lub kilku współdzielonych rozwiązaniach (a więc katalogach najwyższego poziomu w Twojej strukturze), a następnie rozgałęzienie ich z każdym wydaniem dowolnego Rozwiązania.

 0
Author: C. Dragon 76,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 18:55:01

Aby dodać do problemu ścieżki względnej:

Nie jestem pewien czy to problem:
Po prostu checkout Solution1/trunk w katalogu o nazwie "Solution1", podobnie jak w przypadku Solution2: celem 'katalogów' reprezentujących gałęzie jest to, aby nie było widoczne Po zaimportowaniu do obszaru roboczego. Stąd możliwe są ścieżki względne pomiędzy ' Solution1 '(właściwie 'Solution1/trunk') i 'Solution2' (Solution2/trunk).

 0
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 18:58:42

RE: problem ze ścieżką względną i plikiem udostępnionym -

Wydaje się, że jest to specyficzne dla svn, ale to nie jest problem. Jedna inna osoba wspomniała już o osobnych repozytoriach i to chyba najlepsze rozwiązanie, jakie przychodzi mi na myśl w przypadku, gdy masz różne projekty odnoszące się do dowolnych innych projektów. W przypadku, gdy nie masz udostępnionych plików, rozwiązanie OP (jak i wiele innych) będzie działać dobrze.

Nadal pracujemy nad tym i mam 3 różne wysiłki (różnych klientów), które muszę rozwiązać teraz, ponieważ przejąłem konfigurację albo nieistniejącej lub złej kontroli wersji.

 0
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 19:11:49

Mam podobny układ, ale mój kufer, gałęzie, znaczniki na samej górze. Tak więc: / trunk / main,/trunk /utils,/branches/ release/, itp.

Okazało się to bardzo przydatne, gdy chcieliśmy wypróbować inne systemy kontroli wersji, ponieważ wiele narzędzi tłumaczeniowych działało najlepiej z podstawowym podręcznikowym układem SVN.

 0
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 17:23:19