Как вы организуете свой репозиторий контроля версий?
-
03-07-2019 - |
Вопрос
Во-первых, я знаю об этом: Как бы вы организовали хранилище 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
Чтобы очистить словарь: «Решение» означает один продукт, «Проект» - это проект Visual Studio (в результате получается один .dll или один .exe)
Вот так мы планируем выложить хранилище. Основная проблема в том, что у нас есть несколько решений, но мы хотим делиться проектами между решениями. Мы подумали, что на самом деле нет смысла переводить эти общие проекты в собственные решения, и вместо этого мы решили использовать svn: externals для обмена проектами между решениями. Мы также хотим хранить общий набор инструментов и сторонних библиотек в одном месте в хранилище, и они ссылаются на них в каждом решении с помощью svn: externals.
Что вы думаете об этом макете? Особенно про использование SVN: Externals. Это не идеальное решение, но учитывая все плюсы и минусы, это лучшее, что мы могли придумать. Как бы вы это сделали?
Решение
Если вы будете следовать моим рекомендациям, приведенным ниже (у меня есть в течение многих лет), вы сможете:
- помещать каждый проект в любом месте в системе контроля версий, если вы сохраняете структуру из корневого каталога проекта вниз
- создавайте каждый проект где угодно на любом компьютере, с минимальным риском и минимальной подготовкой
- создавать каждый проект полностью автономно, если у вас есть доступ к его двоичным зависимостям (локальные каталоги "библиотека" и "каталоги вывода")
- создавать и работать с любой комбинацией проектов, поскольку они независимы
- создавать и работать с несколькими копиями / версиями одного проекта, поскольку они независимы
- избегайте засорения вашего репозитория исходного кода сгенерированными файлами или библиотеками
Я рекомендую (вот говядина):
<Ол>Определите каждый проект для создания одного основного конечного результата, такого как .DLL, .EXE или .JAR (по умолчанию в Visual Studio).
Структурируйте каждый проект как дерево каталогов с одним корнем.
Создайте сценарий автоматической сборки для каждого проекта в его корневом каталоге, который будет создавать его с нуля, без каких-либо зависимостей от IDE (но не препятствуйте его сборке в IDE, если это возможно). р>
Рассмотрим nAnt для проектов .NET в Windows или что-то подобное в зависимости от вашей ОС, целевой платформы и т. д.
Заставьте каждый скрипт сборки проекта ссылаться на его внешние (сторонние) зависимости из одной локальной общей " библиотеки " каталог, каждый такой двоичный файл ПОЛНОСТЬЮ идентифицируется по версии: % DirLibraryRoot% \ ComponentA-1.2.3.4.dll
, % DirLibraryRoot% \ ComponentB-5.6.7.8.dll
. р>
Сделайте так, чтобы каждый сценарий сборки проекта публиковал основной результат на один локальный общий " output " каталог: % DirOutputRoot% \ ProjectA-9.10.11.12.dll
, % DirOutputRoot% \ ProjectB-13.14.15.16.exe
.
Заставьте каждый скрипт сборки проекта ссылаться на его зависимости через настраиваемые и полностью версионные абсолютные пути (см. выше) в " библиотеке " и «вывод» каталоги, И НЕТ, ГДЕ ЕЩЕ.
НИКОГДА не позволяйте проекту напрямую ссылаться на другой проект или любое его содержимое - разрешайте ссылки только на первичные результаты в " выходные данные " каталог (см. выше).
Сделайте так, чтобы каждый скрипт сборки проекта ссылался на свои необходимые инструменты сборки по настраиваемому и полностью версионному абсолютному пути: % DirToolRoot% \ ToolA \ 1.2.3.4
, % DirToolRoot% \ ToolB \ 5.6.7.8 код>.
Сделайте так, чтобы каждый сценарий сборки проекта ссылался на исходное содержимое по абсолютному пути относительно корневого каталога проекта: $ {project.base.dir} / src
, $ {project. base.dir} / tst
(синтаксис зависит от инструмента сборки).
ВСЕГДА требуется, чтобы скрипт сборки проекта ссылался на КАЖДЫЙ файл или каталог по абсолютному настраиваемому пути (с корнем в каталоге, заданном настраиваемой переменной): $ {project.base.dir} / some / dirs
или $ {env.Variable} / other / dir
.
НИКОГДА не разрешайте скрипту сборки проекта НИЧЕГО ссылаться на относительный путь, например . \ some \ dirs \ here
или .. \ some \ more \ dirs
, ВСЕГДА используйте абсолютные пути.
НИКОГДА не позволяйте сценарию сборки проекта ссылаться на НИЧЕГО, используя абсолютный путь, который не имеет настраиваемого корневого каталога, например C: \ some \ dirs \ here
или \\ сервер \ доля \ больше \ вещи \ есть код>.
Для каждого настраиваемого корневого каталога, на который ссылается скрипт сборки проекта, определите переменную среды, которая будет использоваться для этих ссылок.
Попытайтесь свести к минимуму количество переменных среды, которые необходимо создать для настройки каждого компьютера.
На каждом компьютере создайте сценарий оболочки, который определяет необходимые переменные среды, специфичные дляЭТО машина (и, возможно, специфичная для этого пользователя, если это уместно).
НЕ помещайте машинный скрипт конфигурации в систему управления исходным кодом; вместо этого для каждого проекта передайте копию сценария в корневой каталог проекта в качестве шаблона.
ЗАПРОСИТЕ каждый скрипт сборки проекта, чтобы проверить каждую из его переменных среды, и прервите с осмысленным сообщением, если они не определены.
ЗАПРОСИТЕ каждый сценарий сборки проекта, чтобы проверить все его зависимые исполняемые файлы инструмента сборки, файлы внешних библиотек и зависимые файлы проекта, а также прервать работу со значимым сообщением, если эти файлы не существуют.
RESIST соблазн передать ЛЮБЫЕ сгенерированные файлы в систему управления исходным кодом - нет результатов проекта, нет сгенерированного источника, нет сгенерированных документов и т. д.
Если вы используете IDE, создайте все файлы управления проектом, какие только можете, и не переносите их в систему контроля версий (включая файлы проекта Visual Studio).
Создайте сервер с официальной копией всех внешних библиотек и инструментов, которые будут скопированы / установлены на рабочих станциях разработчиков и сборочных машинах. Сделайте резервную копию вместе с хранилищем управления исходным кодом.
Создайте сервер непрерывной интеграции (сборочную машину) без каких-либо инструментов разработки.
Рассмотрим инструмент для управления внешними библиотеками и результатами, такими как Ivy (используется с Ant).
НЕ используйте 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). В противном случае вы в конечном итоге столкнетесь с ошибкой, и ваш первый
Другие советы
Я считаю, что Прагматическое управление версиями с использованием Subversion имеет все необходимое для организации своего хранилища.
Мы настроили наш сайт так, чтобы он почти полностью совпадал с тем, что вы опубликовали. Мы используем общую форму:
\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" папка - в настоящее время эти типы проектов не попадают в систему управления исходным кодом, и я всегда чувствовал, что они должны.
Зачем все это в одном хранилище? Почему бы просто не создать отдельный репозиторий для каждого проекта (я имею в виду «Решение»)?
Ну, по крайней мере, я привык к подходу «один проект на репозиторий». Ваша структура хранилища кажется мне слишком сложной.
И сколько проектов вы планируете поместить в этот большой репозиторий? 2? 3? 10? 100? Р>
А что вы делаете, когда отмените разработку одного проекта? Просто удалите его из дерева репозитория, чтобы его было трудно найти в будущем. Или оставить это навсегда? Или когда вы хотите полностью переместить один проект на другой сервер?
А как насчет всех этих номеров версий? Номера версий одного проекта имеют вид 2, 10, 11, а другого - 1, 3, 4, 5, 6, 7, 8, 9, 12 ...
Может быть, я глуп, но мне нравится один проект на репозиторий.
Я думаю, что основным недостатком предлагаемой структуры является то, что общие проекты будут иметь версии только с первым решением, к которому они были добавлены (если svn: externals не более изящен, чем я себе представляю). Например, когда вы создаете ветку для первого выпуска Solution2, Project1 не будет разветвлен, так как он живет в Solution1. Если вам потребуется выполнить сборку из этой ветви позднее (выпуск QFE), она будет использовать последнюю версию Project1, а не версию Project1 на момент перехода.
По этой причине может оказаться полезным поместить общие проекты в одно или несколько общих решений (и, следовательно, каталогов верхнего уровня в вашей структуре), а затем ветвить их с каждым выпуском любого решения. . р>
Чтобы добавить к проблеме относительного пути:
Я не уверен, что это проблема:
Просто выберите Solution1 / trunk в каталоге с именем «Solution1», то же самое для Solution2: цель «каталогов», фактически представляющих ветви, состоит в том, чтобы не быть видимым после импорта в рабочую область. Следовательно, возможны относительные пути между «Solution1» (фактически «Solution1 / trunk») и «Solution2» (Solution2 / trunk).
RE: относительный путь и проблема с общим файлом -
Кажется, это специфично для SVN, но это не проблема. Еще один человек уже упомянул отдельные репозитории, и это, вероятно, лучшее решение, которое я могу придумать в случае, когда у вас есть разные проекты, относящиеся к произвольным другим проектам. В случае, если у вас нет общих файлов, тогда решение OP (как и многие другие) будет работать нормально. Р>
Мы все еще работаем над этим, и у меня есть 3 разных попытки (разных клиентов), которые мне нужно решить прямо сейчас, так как я взял на себя настройку либо несуществующего, либо плохого контроля версий. Р>
У меня похожий макет, но мой ствол, ветви, метки полностью вверху. Итак: / trunk / main, / trunk / utils, / branch / release / и т. Д.
Это оказалось очень удобным, когда мы захотели опробовать другие системы контроля версий, потому что многие инструменты перевода лучше всего работали с базовой версией SVN из учебника.