Как организовать репозиторий управления версиями?

Во-первых, я знаю об этом: Как бы вы организовали репозиторий Subversion для проектов домашнего программного обеспечения? Затем, актуальный вопрос: Моя команда реструктурирует наш репозиторий, и я ищу советы о том, как его организовать. (SVN в этом случае). Вот что мы придумали. У нас есть один репозиторий, несколько проектов и множественные перекрестные ссылки 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

Чтобы очистить словарь: решение означает отдельный продукт, Project - это проект Visual Studio (который приводит к созданию одного DLL или одного .exe)

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

Что вы думаете об этом макете? Особенно об использовании svn: externals. Это не идеальное решение, но, учитывая все плюсы и минусы, это лучшее, что мы могли бы придумать. Как вы это сделаете?

Ответ 1

Если вы следуете моим рекомендациям ниже (у меня есть годы), вы сможете:

- поместите каждый проект в любом месте в исходное управление, если вы сохраните структуру из корневого каталога проекта вниз.

- строить каждый проект в любом месте на любой машине с минимальным риском и минимальной подготовкой

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

- создавать и работать с любой комбинацией проектов, поскольку они независимы

- создавать и работать с несколькими копиями/версиями одного проекта, так как они независимы

- избегайте загромождения исходного репозитория с помощью сгенерированных файлов или библиотек.

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

  • Определите каждый проект для создания одного основного продукта, такого как .DLL,.EXE или .JAR(по умолчанию в Visual Studio).

  • Структура каждого проекта как дерева каталогов с одним корнем.

  • Создайте автоматическую сборку script для каждого проекта в корневой директории, которая будет строить ее с нуля, без НИКАКИХ зависимостей от IDE (но не предотвращайте ее создание в среде IDE, если это возможно).

  • Рассмотрим nAnt для .NET-проектов в Windows или что-то подобное на основе вашей ОС, целевой платформы и т.д.

  • Сделать каждую конструкцию проекта script ссылкой на ее внешние (сторонние) зависимости из одного локального общего "библиотечного" каталога с каждым таким бинарным файлом, ПОЛНОСТЬЮ идентифицированным по версии: %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  • Сделать каждую сборку проекта script опубликовать основной вывод в один локальный общий "выходной" каталог: %DirOutputRoot%\ProjectA-9.10.11.12.dll, %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  • Сделать каждую конструкцию проекта script ссылкой на ее зависимости через настраиваемые и полностью версированные абсолютные пути (см. выше) в каталогах "Библиотека" и "Выход", И НЕТ ГДЕ ЕЩЕ.

  • НИКОГДА не позволяйте проекту напрямую ссылаться на другой проект или какое-либо его содержимое - разрешать ссылки на первичные результаты в каталоге "output" (см. выше).

  • Сделать каждую конструкцию проекта script ссылкой на необходимые инструменты построения с помощью настраиваемого и полностью версированного абсолютного пути: %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  • Сделайте каждый проект build script ссылкой на исходный контент по абсолютному пути относительно корневого каталога проекта: ${project.base.dir}/src, ${project.base.dir}/tst (синтаксис зависит от инструмента построения).

  • ВСЕГДА требуется сборка проекта script для ссылки КАЖДОГО файла или каталога через абсолютный, настраиваемый путь (внедренный в каталог, заданный настраиваемой переменной): ${project.base.dir}/some/dirs или ${env.Variable}/other/dir.

  • НИКОГДА не допускайте, чтобы проект build script ссылался на ANYTHING с относительным путем, как .\some\dirs\here или ..\some\more\dirs, ВСЕГДА используют абсолютные пути.

  • НИКОГДА не допускайте, чтобы проект build script ссылался на НИЧЕГО, используя абсолютный путь, который не имеет настраиваемого корневого каталога, например C:\some\dirs\here или \\server\share\more\stuff\there.

  • Для каждого настраиваемого корневого каталога, на который ссылается сборка проекта script, определите переменную среды, которая будет использоваться для этих ссылок.

  • Попытка минимизировать количество переменных среды, которые необходимо создать для настройки каждой машины.

  • На каждой машине создайте оболочку script, которая определяет необходимые переменные среды, специфичные для машины THAT (и, возможно, специфические для этого пользователя, если это необходимо).

  • НЕ помещайте конфигурационную оболочку машины script в исходный элемент управления; вместо этого для каждого проекта скопируйте копию script в корневой каталог проекта как шаблон.

  • ЗАПРОСИТЕ каждый проект build script, чтобы проверить каждую из его переменных окружения и прервать его значимым сообщением, если они не определены.

  • ЗАПРЕЩАЙТЕ каждую проектную сборку script, чтобы проверить все исполняемые файлы зависимого исполняемого файла сборки, файлы внешних библиотек и файлы, зависящие от проекта, и прервать значимое сообщение, если эти файлы не существуют.

  • УДАЛИТЬ искушение совершить ЛЮБЫЕ сгенерированные файлы в исходное управление - нет результатов проекта, нет сгенерированного источника, не созданных документов и т.д.

  • Если вы используете IDE, сгенерируйте любые файлы управления проектами и не передавайте их в исходный элемент управления (включая файлы проекта Visual Studio).

  • Создайте сервер с официальной копией всех внешних библиотек и инструментов, которые будут скопированы/установлены на рабочих станциях разработчиков и постройте машины. Создайте резервную копию вместе с репозиторием исходного кода.

  • Установите сервер непрерывной интеграции (сборщик) без каких-либо средств разработки.

  • Рассмотрим инструмент для управления внешними библиотеками и конечными продуктами, такими как Ivy (используется с Ant).

  • НЕ используйте Maven - он изначально сделает вас счастливыми и в конечном итоге заставит вас плакать.

Обратите внимание, что это не относится к Subversion, и большинство из них является общим для проектов, ориентированных на любую ОС, аппаратное обеспечение, платформу, язык и т.д. Я использовал немного синтаксиса OS и инструмента, но только для иллюстрации. Я надеюсь, что вы переведете на свою ОС или инструмент по выбору.

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

Пожалуйста, не используйте внешние субстраты Subversion (или аналогичные в других инструментах), они являются анти-шаблонами и, следовательно, не нужны.

При реализации непрерывной интеграции или даже когда вы просто хотите автоматизировать процесс выпуска, создайте для него script. Создайте единую оболочку script, которая: принимает параметры имени проекта (как указано в репозитории) и имя тега, создает временный каталог в настраиваемом корневом каталоге, проверяет источник для данного имени проекта и имени тега (по построение соответствующего URL-адреса в случае Subversion) в этот временный каталог, выполняет чистую сборку, которая запускает тесты и пакеты для доставки. Эта оболочка script должна работать над любым проектом и должна быть проверена в качестве источника в качестве части вашего проекта "Инструменты сборки". Ваш сервер непрерывной интеграции может использовать этот script в качестве основы для создания проектов или даже может предоставить его (но вы все равно можете захотеть своего).

@VonC: вы не хотите работать всегда с ant.jar ", а не" ant -abcdjar "после того, как вы сожжетесь, когда ваша сборка script сломается, потому что вы неосознанно запускали ее с помощью несовместимая версия Ant. Это особенно характерно для Ant 1.6.5 и 1.7.0. Обобщая, вы ВСЕГДА хотите знать, какая конкретная версия компонента EVERY используется, включая вашу платформу (Java A.B.C.D) и ваш инструмент сборки (Ant E.F.G.H). В противном случае вы в конце концов столкнетесь с ошибкой, и ваша первая проблема BIG будет отслеживать, какие версии ваших различных компонентов задействованы. Это просто лучше решить эту проблему.

Ответ 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", - в настоящее время эти типы проектов не входят в элемент управления Source, и я всегда чувствовал, что они должны.

Ответ 4

Почему все это в одном хранилище? Почему бы просто не иметь отдельный репозиторий для каждого проекта (я имею в виду "Решение" )?

Ну, по крайней мере, я привык к подходу с одним проектом за репозиторием. Структура вашего хранилища кажется мне сложной.

И сколько проектов вы планируете вложить в этот большой репозиторий? 2? 3? 10? 100?

И что вы будете делать, если отмените разработку одного проекта? Просто удалите его из дерева репозитория, чтобы его стало трудно найти в будущем. Или оставить его навсегда? Или когда вы хотите полностью переместить один проект на другой сервер?

А как насчет беспорядка всех этих номеров версий? Номера версий одного проекта идут как 2, 10, 11, а остальные идут как 1, 3, 4, 5, 6, 7, 8, 9, 12...

Возможно, я глуп, но мне нравится один проект в репозитории.

Ответ 5

У меня есть аналогичный макет, но мой сундук, ветки, теги полностью вверху. Итак:/trunk/main,/trunk/utils,/branches/release/и т.д.

Это оказалось очень удобно, когда мы хотели попробовать другие системы управления версиями, потому что многие инструменты перевода лучше всего работали с макетом SVN основного учебника.

Ответ 6

Я считаю, что основной недостаток предлагаемой структуры состоит в том, что совлокальные проекты будут версироваться только с первым решением, к которому они были добавлены (если только svn: externals больше, чем я представляю). Например, когда вы создаете ветвь для первой версии Solution2, Project1 не будет разветвленной, так как она живет в Solution1. Если вам нужно построить из этой ветки позднее (выпуск QFE), она будет использовать последнюю версию Project1, а не версию Project1 во время ветки.

По этой причине может быть выгодным разместить совместно используемые проекты в одном или нескольких общих решениях (и, следовательно, в каталогах верхнего уровня в вашей структуре), а затем разделить их с каждой версией любого решения.

Ответ 7

Чтобы добавить к проблеме относительного пути:

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

Ответ 8

RE: проблема относительного пути и общего файла -

Кажется, что это svn конкретный, но это не проблема. Еще один человек уже упомянул о отдельных репозиториях, и это, вероятно, лучшее решение, о котором я могу думать в случае, когда у вас есть разные проекты, относящиеся к произвольным другим проектам. В случае, если у вас нет общих файлов, решение OP (как и многие другие) будет работать нормально.

Мы все еще работаем над этим, и у меня есть 3 разных усилия (разные клиенты), которые я должен решить прямо сейчас, так как я взял на себя настройку либо несуществующего, либо плохого контроля версий.