Как вы организуете свой репозиторий контроля версий? - PullRequest
108 голосов
/ 21 октября 2008

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

Ответы [ 8 ]

92 голосов
/ 20 ноября 2008

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

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

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

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

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

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

- избегайте засорения вашего хранилища контроля версий сгенерированными файлами или библиотеками

Я рекомендую (вот говядина):

  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. Сделайте так, чтобы каждый скрипт сборки проекта ссылался на свои зависимости через настраиваемые и полностью версионные абсолютные пути (см. Выше) в каталогах "library" и "output", И НЕТ, ГДЕ ЕЩЕ.

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

  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-a.b.c.d.jar" после того, как вы сгорели, когда сломался ваш скрипт сборки, потому что вы по незнанию запустили его с несовместимой версией Ant. Это особенно распространено между Ant 1.6.5 и 1.7.0. Обобщая, вы ВСЕГДА хотите знать, какая конкретная версия КАЖДОГО компонента используется, включая вашу платформу (Java A.B.C.D) и ваш инструмент сборки (Ant E.F.G.H). В противном случае вы в конечном итоге столкнетесь с ошибкой, и ваша первая БОЛЬШАЯ проблема будет отслеживать, какие версии ваших компонентов задействованы. Просто лучше решить эту проблему заранее.

3 голосов
/ 21 октября 2008

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

\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 голосов
/ 21 октября 2008

Я считаю, что Pragmatic Version Control с использованием Subversion имеет все необходимое для организации вашего хранилища.

1 голос
/ 21 октября 2008

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

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

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

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

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

Может быть, я глуп, но мне нравится один проект на репозиторий.

0 голосов
/ 21 октября 2008

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

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

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

0 голосов
/ 21 октября 2008

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

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

0 голосов
/ 21 октября 2008

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

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

0 голосов
/ 21 октября 2008

У меня похожий макет, но мой ствол, ветви, метки полностью вверху. Итак: / trunk / main, / trunk / utils, / branch / release / и т. Д.

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

...