Як організувати сховище контролю версій?


108

По-перше, я знаю про це: як би ви організували сховище Subversion для внутрішніх програмних програм? Далі, власне питання: Моя команда реструктурує наше сховище, і я шукаю підказки, як його організувати. (SVN в цьому випадку). Ось що ми придумали. У нас є одне сховище, кілька проектів і кілька svn: зовнішні перехресні посилання

\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

Щоб очистити словниковий запас: Рішення означає єдиний продукт, Project - це проект Visual Studio (який призводить до одного .dll або single .exe)

Ось так ми плануємо викласти сховище. Основне питання полягає в тому, що у нас є декілька рішень, але ми хочемо поділитись проектами серед рішень. Ми думали, що немає сенсу пересувати ці спільні Проекти до власних рішень, і замість цього вирішили використовувати svn: externals для обміну Проектами серед Рішень. Ми також хочемо зберегти загальний набір інструментів і сторонніх бібліотек на одному місці у сховищі, і вони посилаються на них у кожному рішення з svn: externals.

Що ви думаєте про цей макет? Особливо щодо використання svn: зовнішніх. Це не ідеальне рішення, але враховуючи всі плюси і мінуси, це найкраще, що ми могли придумати. Як би ви це зробили?


Ви впевнені, що маєте на увазі "треш"? А точніше "сміття"?
ssc

Відповіді:


92

Якщо ви будете дотримуватися моїх рекомендацій нижче (я роками), ви зможете:

- покладіть кожен проект де-небудь у керування джерелами, якщо ви збережете структуру з кореневого каталогу проекту вниз

- будуйте кожен проект у будь-якому місці на будь-якій машині, з мінімальним ризиком та мінімальною підготовкою

- будуйте кожен проект повністю автономним, якщо у вас є доступ до його бінарних залежностей (локальні каталоги "бібліотека" та "вихід")

- будувати та працювати з будь-якою комбінацією проектів, оскільки вони незалежні

- будувати та працювати з декількома копіями / версіями одного проекту, оскільки вони незалежні

- уникайте захаращування вашого сховища керування джерелом з генерованими файлами чи бібліотеками

Рекомендую (ось яловичина):

  1. Визначте кожен проект для отримання єдиного основного результату, такого як .DLL, .EXE або .JAR (за замовчуванням для Visual Studio).

  2. Структуруйте кожен проект як дерево каталогів з одним коренем.

  3. Створіть автоматичний сценарій збірки для кожного проекту в його кореневому каталозі, який буде створювати його з нуля, без залежностей від IDE (але не заважайте будувати його в IDE, якщо це можливо).

  4. Розглянемо проекти nAnt для .NET в Windows або щось подібне на основі вашої ОС, цільової платформи тощо.

  5. Зробіть, щоб кожен сценарій побудови проекту посилався на його зовнішні (сторонні) залежності від однієї локальної спільної бібліотеки "бібліотека", при цьому кожен такий бінарний ПОЛІТКО визначається версією: %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  6. Зробіть, щоб кожен сценарій побудови проекту публікував основний доступ до однієї локальної спільної "вихідної" каталогу: %DirOutputRoot%\ProjectA-9.10.11.12.dll, %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. Зробіть, щоб кожен сценарій побудови сценарію посилався на його залежність за допомогою настроюваних та повністю перетворених абсолютних шляхів (див. Вище) в каталогах "бібліотека" та "вихід", і НЕ БУДЕ, де інше.

  8. НІКОЛИ не дозволяйте проекту безпосередньо посилатися на інший проект або будь-який його вміст - дозволяйте посилатися лише на основні результати у каталозі "вихід" (див. Вище).

  9. Зробіть для кожного сценарію побудови проекту посилання на його необхідні інструменти побудови за допомогою настроюваного та повністю перетвореного абсолютного шляху: %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  10. Зробіть кожен проект збірки сценарій змісту посилання джерело за абсолютним шляху щодо кореневої директорії проекту: ${project.base.dir}/src, ${project.base.dir}/tst(синтаксис варіюється в залежності від інструменту збірки).

  11. ЗАВЖДИ потрібен сценарій побудови проекту для посилання на кожен файл або каталог через абсолютний конфігуруваний шлях (коріння у каталозі, визначеному конфігуруемою змінною): ${project.base.dir}/some/dirsабо ${env.Variable}/other/dir.

  12. НІКОЛИ не дозволяйте сценарію побудови проекту посилатись на ЯКЩО з відносним шляхом, як-от .\some\dirs\hereабо ..\some\more\dirs, ЗАВЖДИ використовуйте абсолютні шляхи.

  13. НІКОЛИ не дозволяйте сценарію побудови проекту посилатися на будь-яке, використовуючи абсолютний шлях, що не має настроюваного кореневого каталогу, як C:\some\dirs\hereабо \\server\share\more\stuff\there.

  14. Для кожного настроюваного кореневого каталогу, на який посилається сценарій побудови проекту, визначте змінну середовища, яка буде використовуватися для цих посилань.

  15. Спроба мінімізувати кількість змінних середовища, які ви повинні створити для налаштування кожної машини.

  16. На кожній машині створіть скрипт оболонки, який визначає необхідні змінні середовища, специфічні для ТОМУ машині (і, можливо, специфічні для цього користувача, якщо це доречно).

  17. НЕ кладіть сценарій оболонки конфігурації для машини в управління джерелом; натомість для кожного проекту виконайте копію скрипту в кореневому каталозі проекту як шаблон.

  18. ЗАПИТАТИ кожен сценарій побудови проекту, щоб перевірити кожну зі змінних його середовища, і скасувати змістовне повідомлення, якщо вони не визначені.

  19. ЗАПИТАТИ кожен сценарій побудови проекту, щоб перевірити кожен з його залежних виконуваних інструментів збирання, зовнішні файли бібліотеки та залежні файли, доступні для проекту, і скасувати змістовне повідомлення, якщо цих файлів не існує.

  20. ПІДТРИМКУЙТЕ спокусу запустити будь-які файли, створені у керування джерелами - ніяких результатів проекту, жодного згенерованого джерела, жодних згенерованих документів тощо.

  21. Якщо ви використовуєте IDE, генеруйте будь-які файли управління проектом, які ви можете, і не змушуйте їх керувати джерелом (це включає файли проектів Visual Studio).

  22. Створіть сервер з офіційною копією всіх зовнішніх бібліотек та інструментів, який слід копіювати / встановлювати на робочих станціях розробника та створювати машини. Створіть резервну копію разом із сховищем керування джерелом.

  23. Створіть сервер безперервної інтеграції (побудуйте машину) без будь-яких інструментів розвитку.

  24. Розглянемо інструмент для керування своїми зовнішніми бібліотеками та результатами, наприклад Ivy (використовується з Ant).

  25. НЕ використовуйте Maven - це спочатку зробить вас щасливими, а з часом змусить вас плакати.

Зауважте, що нічого з цього не є специфічним для Subversion, і більшість з них є загальним для проектів, націлених на будь-яку ОС, апаратне забезпечення, платформу, мову тощо. Я використовував трохи синтаксису, орієнтованого на ОС та інструменти, але лише для ілюстрації- -Я впевнений, що ви переведете на вашу ОС або інструмент за вибором.

Додаткова примітка щодо рішень Visual Studio: не покладіть їх на контроль джерел! При такому підході вони вам взагалі не потрібні або ви можете їх генерувати (як і файли проектів Visual Studio). Однак я вважаю, що найкраще залишити файли рішення окремим розробникам для створення / використання, як вони вважають за потрібне (але не зареєстроване у контролі джерела). Я зберігаю Rob.slnфайл на своїй робочій станції, з якого я посилаюсь на свій поточний проект. Оскільки мої проекти є автономними, я можу додавати / видаляти проекти за бажанням (це означає, що відсутні посилання на залежність від проектів).

Будь ласка, не використовуйте Subversion зовнішні (або подібні в інших інструментах), вони є анти-шаблоном і, отже, непотрібними.

Коли ви впроваджуєте безперервну інтеграцію або навіть коли ви просто хочете автоматизувати процес випуску, створіть для нього сценарій. Створіть єдиний скрипт оболонки, який: приймає параметри назви проекту (як зазначено у сховищі) та ім'я тегу, створює тимчасовий каталог у налаштованому кореневому каталозі, перевіряє джерело для вказаного імені проекту та імені тега (конструюючи відповідна URL-адреса у випадку Subversion) до цього тимчасового каталогу, виконує чисту збірку, яка запускає тести та пакує доставлені. Цей скрипт оболонки повинен працювати над будь-яким проектом і повинен бути перевірений у контролі джерела як частини проекту "інструменти побудови". Ваш сервер безперервної інтеграції може використовувати цей скрипт як основу для побудови проектів, а може навіть надавати його (але ви все ще можете хотіти свого).

@VonC: Ви не хочете працювати завжди з "ant.jar", а не з "ant-abcdjar" після того, як ви отримаєте опік, коли ваш сценарій збірки зламається, оскільки ви несвідомо запустили його з несумісною версією Ant. Особливо часто це зустрічається між мурахами 1.6.5 та 1.7.0. Узагальнюючи, ВИНАГИ хочете дізнатися, яка конкретна версія КОЖНОГО компонента використовується, включаючи вашу платформу (Java ABCD) та інструмент побудови (Ant EFGH). В іншому випадку ви з часом зіткнетеся з помилкою, і ваша перша проблема BIG буде відслідковувати, які версії різних ваших компонентів задіяні. Просто краще вирішити цю проблему наперед.


6
Стільки моментів критикувати ... достатньо сказати, що це не універсальний рецепт! Пункти 5 і 6, зокрема, не так, коли проект великий і кількість третіх сторін важлива: ви хочете постійно працювати з "ant.jar", а не "ant1.5.4.jar" або продуктом myProduct .exe, а не 1.3.exe
VonC

5
Однак +1 за багато інших ваших питань, які є дійсними і дуже висловлюються за ваш великий досвід роботи з даною темою.
VonC

3
Мені б хотілося почути та взаємодіяти з вашою критикою - кожна точка базується на вирішенні поганого досвіду великих проектів. Наприклад, вирішення питання про те, які версії представлені Xxx.jar та Yyy.exe, особливо коли на них посилається буквально десяток примірників.
Роб Вільямс

2
@Rob - Чи можете Ви детальніше розглянути тему "зовнішні антипатерні"? Я поставив це питання тут: stackoverflow.com/questions/338824/…
Кен

3
@Makis: Ви б помилилися, якби №12 не збалансовано №13. Кожне посилання на файл або каталог у рамках кожного проекту повинно здійснюватися за допомогою абсолютного шляху, який починається з настроюваної змінної кореневого каталогу, наприклад $ {basedir} /sub/dir/file.txt в Ant.
Роб Вільямс

3

Я вважаю, що Прагматичний контроль версій за допомогою Subversion має все необхідне для організації вашого сховища.


7
@bal Будь ласка, не використовуйте сервіси скорочення URL-адрес. Це набагато краще , щоб сказати : «Тепер в його друге видання: Прагматичний контроль версій з допомогою Subversion »
meagar

3

Ми налаштували наше, щоб майже точно відповідати тому, що ви розмістили. Ми використовуємо загальну форму:

\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

Хоча я вважаю, що не такий повний, як ваш приклад, він добре працює для нас і дозволяє нам тримати речі окремо. Мені подобається ідея, що кожен користувач має папку "Thrash" - в даний час ці типи проектів не знаходяться в контролі джерел, і я завжди вважав, що вони повинні.


3
Я здивований, що у вас є окремий каталог документів, які не змінюються між версіями ... Я ніколи не мав задоволення працювати над таким продуктом! :)
ARKBAN

1

Навіщо це все в одному сховищі? Чому б просто не мати окремого сховища для кожного проекту (я маю на увазі "Рішення")?

Ну, принаймні, я звик до підходу один проект на репозиторій. Ваша структура сховища мені здається надскладною.

І скільки проектів ви плануєте розмістити в цьому великому сховищі? 2? 3? 10? 100?

А що ви робите, коли скасовуєте розробку одного проекту? Просто видаліть його з дерева сховища, щоб у майбутньому його було важко знайти. Або залишити його лежати довкола назавжди? Або коли ви хочете взагалі перенести один проект на інший сервер?

А як щодо безладу всіх цих номерів версій? Номери версій одного проекту складаються як 2, 10, 11, а іншого - 1, 3, 4, 5, 6, 7, 8, 9, 12 ...

Можливо, я дурний, але мені подобається один проект на сховище.


1. Одне сховище - це політика компанії, не може це змінити. 2. У нас буде близько десятка рішень. 3. Під номерами версій ви маєте на увазі редакції? Це не для нас питання.
Кшиштоф Козміч

Хороша структура проекту не повинна забувати решту структури сховища, особливо стосовно одного або багатьох сховищ. Будь ласка, дивіться мою детальну відповідь.
Роб Вільямс

1
Зверніть увагу, що наявність декількох сховищ у багатьох (найбільш?) Інструментах управління джерелами може бути ДУЖЕ дорогим, наприклад, коли ви впроваджуєте безпеку.
Роб Вільямс

0

Я думаю, що головним недоліком запропонованої структури є те, що спільні проекти будуть впорядковані лише з першим рішенням, до якого вони були додані (якщо тільки svn: зовнішні файти не фантастичніші, ніж я собі уявляю). Наприклад, коли ви створюєте гілку для першого випуску Solution2, Project1 не буде розгалуженим, оскільки він живе в Solution1. Якщо вам потрібно пізніше побудувати з цієї гілки (випуск QFE), вона буде використовувати останню версію Project1, а не версію Project1 на час роботи гілки.

З цієї причини може бути вигідним розмістити спільні проекти в одному або декількох спільних рішеннях (і, таким чином, каталоги вищого рівня у вашій структурі), а потім розгалужувати їх з кожним випуском будь-якого рішення.


Ви в деякій мірі праві. Але ми можемо оновити посилання, якщо хочемо. І розміщення спільних проектів у власному рішенні також не має особливого сенсу. Хоча я хотів би знайти краще рішення, ніж svn: зовнішні місця в усьому світі.
Кшиштоф Козміч

Що ви маєте на увазі під "оновленням довідки, якщо ми хочемо"? Я не бачу, як ви могли б розгалужувати Project1 (що здається бажаним щоразу, коли ви розгалужуєте Solution2) без розгалуження Solution1.
C. Dragon 76,

Будь ласка, ознайомтеся з моєю детальною відповіддю, зокрема, що НЕ вкладайте рішення Visual Studio у контроль джерел.
Роб Вільямс

0

Щоб додати до питання відносного шляху:

Я не впевнений, що це проблема:
просто замовте Solution1 / магістраль під каталогом під назвою "Solution1", імено для Solution2: мета "каталогів", що насправді представляють гілки, не буде видно, коли вони імпортовані в робочу область. Отже, можливі відносні шляхи між 'Solution1' (фактично 'Solution1 / trunk') і 'Solution2' (Solution2 / trunk).


Це зламається дуже легко, будь ласка, дивіться мою детальну відповідь.
Роб Вільямс

0

RE: відносний шлях і проблема спільного файлу -

Здається, це специфічно для svn, але це не проблема. Ще одна людина вже згадувала окремі сховища, і це, мабуть, найкраще рішення, про яке я можу придумати, якщо у вас є різні проекти, що стосуються довільних інших проектів. У випадку, коли у вас немає спільних файлів, рішення OP (як і багато інших) буде добре працювати.

Ми все ще працюємо над цим, і в мене є три різні зусилля (різні клієнти), які я маю вирішити зараз, оскільки я взяв на себе налаштування або неіснуючого, або поганого контролю версій.


Наявність проектів, що стосуються інших проектів, створює кошмар у підтримці, оскільки залежність зростає експоненціально, а посилання є ДУЖЕ крихкими. Будь ласка, дивіться мою детальну відповідь.
Роб Вільямс

0

У мене схожий макет, але мій стовбур, гілки, мітки повністю вгорі. Отже: / trunk / main, / trunk / utils, / відділення / випуск / тощо.

Це виявилося дуже зручним, коли ми хотіли спробувати інші системи управління версіями, оскільки багато інструментів перекладу найкраще працювали з базовим компонуванням SVN підручника.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.