Структура проектов в управлении версиями
Я знаю, что есть как минимум 10 разных способов структурировать проект в системе контроля версий. Мне любопытно, какие методы используются и какие у вас работают. Я работал с SVN, TFS и в настоящее время / к сожалению VSS. Я видел, что управление версиями реализовано очень плохо и просто нормально, но никогда не получалось.
Просто чтобы начать игру, вот обзор того, что я видел.
Этот пример основан на SVN, но применяется к большинству VCS (не столько к распределенному управлению версиями).
ветвить отдельные проекты, которые являются частью сайта / подразделения / веб / имя_проекта /vb/src/[транк | филиалы | теги]
Разветвите весь сайт, в случае, который я видел, весь сайт, за исключением основных компонентов, был разветвлен. / Деление / [ствол | ветвь | теги]/ Web / Projectname / VB / SRC /
Используйте основную линию по умолчанию, только ветвь, когда это необходимо для огромных изменений.
9 ответов
Мы практикуем высококомпонентную разработку с использованием Java, у нас есть около 250 модулей в транке, которые имеют независимые жизненные циклы. Зависимости управляются через Maven (это лучшая практика), каждая итерация (раз в две недели) активно разрабатываемых модулей помечается новой версией. Трехзначные номера версий со строгой семантикой (major.minor.build - значительные изменения означают обратную несовместимость, незначительные изменения означают обратную совместимость, а изменения номера сборки означают обратную и прямую совместимость). Наш конечный программный продукт представляет собой сборку, которая включает в себя десятки отдельных модулей, опять же как зависимости Maven.
Мы разветвляем модули / сборки, когда нам нужно сделать исправление ошибки или усовершенствование для выпущенной версии, и мы не можем предоставить версию HEAD. Помечая все версии, это легко сделать, но ветки по-прежнему подвергаются значительным административным издержкам (особенно при синхронизации веток с определенными наборами изменений HEAD), которые частично вызваны нашими инструментами, Subversion является неоптимальным для управления ветвями.
Мы находим, что довольно плоская и прежде всего предсказуемая древовидная структура в хранилище имеет решающее значение. Это позволило нам создавать инструменты выпуска, которые устраняют большую часть боли и опасности от процесса ручного выпуска (обновленные примечания к выпуску, компиляции проектов, тесты модульных тестов, создание тегов, отсутствие зависимостей SNAPSHOT и т. Д.). Старайтесь не помещать слишком много категоризации или другой логики в древовидную структуру.
Мы примерно делаем что-то вроде следующего:
svnrepo/
trunk/
modules/
m1/ --> will result in jar file
m2/
...
assemblies/
a1/
...
tags/
modules/
m1/
1.0.0/
1.0.1/
1.1.0/
m2/
...
assemblies/
a1/
iteration-55/
...
branches/
m1/
1.0/
...
Что касается внешних зависимостей, я не могу переоценить что-то вроде Maven: управляйте своими зависимостями как ссылками на версионные, уникально идентифицированные двоичные артефакты в хранилище.
Для целостной структуры модуля / проекта: придерживайтесь стандарта. Однородность является ключевым. Опять же, Maven может помочь здесь, так как он диктует структуру. Многие структуры хороши, если вы придерживаетесь их.
Пример для SVN:
хобот/
ветка/
теги /
Ствол должен храниться в том месте, где вы всегда можете вытолкнуть его из спуска. Не должно быть больших зияющих ошибок, о которых вы знаете (конечно, в конечном итоге они будут, но к этому следует стремиться).
Каждый раз, когда вам нужно сделать новую функцию, внести изменения в дизайн, что угодно, ветвь. Отметьте эту ветку в начале. Затем, когда вы закончите с тегом ветки в конце. Это помогает с слиянием обратно в ствол.
Каждый раз, когда вам нужно нажать релиз, пометить. Таким образом, если что-то пойдет не так, вы можете вернуться к предыдущему выпуску.
Эта настройка поддерживает максимально возможную чистоту транка и позволяет быстро исправлять ошибки и устранять их, сохраняя при этом большую часть разработки в филиалах.
Изменить: Для сторонних вещей это зависит. Если я могу избежать этого, у меня нет контроля над исходным кодом. Я держу его в каталоге вне системы контроля версий и включаю оттуда. Для таких вещей, как jquery, я оставляю его под контролем исходного кода. Причина в том, что это упрощает мой скрипт для нажатия. Я могу просто сделать это сделать экспорт SVN и Rsync.
Для своих проектов я всегда использую эту структуру.
- хобот
- конфиг
- документы
- SQL
- начальная
- обновления
- ЦСИ
- приложение
- тестовое задание
- третья вечеринка
- Lib
- инструменты
- теги
- ветви
- config - Используется для хранения шаблонов конфигурации моего приложения. В процессе сборки я беру эти шаблоны и заменяю токены-заполнители фактическими значениями в зависимости от того, какую конфигурацию я собираю.
- документы - любая документация приложения размещается здесь.
- Я разбиваю свои сценарии SQL на две директории. Один для начальной настройки базы данных, когда вы начинаете заново, и другое место для моих сценариев обновления, которые запускаются на основе номера версии базы данных.
- src - исходные файлы приложения. Здесь я разбиваю исходные файлы на основе приложений и тестов.
- thirdparty - здесь я размещаю сторонние библиотеки, на которые я ссылаюсь, внутри своего приложения и недоступные в GAC. Я разделил их на основе lib и инструментов. Каталог lib содержит библиотеки, которые должны быть включены в настоящее приложение. Каталог tools содержит библиотеки, на которые ссылается мое приложение, но они используются только для запуска модульных тестов и компиляции приложения.
Мой файл решения помещается прямо в директорию транка вместе с моими файлами сборки.
Я могу оценить логику не помещать двоичные файлы в репозиторий, но я думаю, что это также имеет огромное преимущество. Если вы хотите иметь возможность извлекать конкретную ревизию из прошлого (обычно более старый тег), мне нравится иметь возможность получить все, что мне нужно, из проверки svn. Конечно, это не относится к Visual Studio или.NET Framework, но наличие правильной версии nant, nunit, log4net и т. Д. Позволяет действительно легко перейти от извлечения к сборке. Таким образом, начать работу так же просто, как "svn co project" и "nant build".
Одна вещь, которую мы делаем, это помещаем бинарные файлы ThirdParty в отдельное дерево и используем svn: external, чтобы получить нужную нам версию. Чтобы упростить жизнь, у нас будет папка для каждой использованной версии. Например, мы можем внести папку ThirdParty/Castle/v1.0.3 в текущий проект. Таким образом, все, что нужно для сборки / тестирования продукта, находится внутри или под корнем проекта. Наш опыт показывает, что обмен дисковым пространством того стоит.
Я предпочитаю мелкозернистые, очень организованные, автономные, структурированные репозитории. Существует диаграмма, иллюстрирующая общий (идеальный) подход процесса обслуживания хранилища. Например, моя первоначальная структура репозитория (должна быть у каждого репозитория проекта):
/project
/trunk
/tags
/builds
/PA
/A
/B
/releases
/AR
/BR
/RC
/ST
/branches
/experimental
/maintenance
/versions
/platforms
/releases
PA
означает пре-альфа A
означает альфа B
означает бета AR
означает альфа-релиз BR
означает бета-релиз RC
означает освобождение кандидата ST
означает стабильный
Существуют различия между сборками и выпусками.
- Теги в папке builds имеют номер версии, соответствующий шаблону
N.x.K
, гдеN
а такжеK
целые числа. Примеры:1.x.0
,5.x.1
,10.x.33
- Теги в папке релизов имеют номер версии, соответствующий шаблону
N.M.K
, гдеN
,M
а такжеK
целые числа. Примеры:1.0.0
,5.3.1
,10.22.33
,
Недавно я разработал тренинг, посвященный управлению конфигурацией программного обеспечения, где я описываю подход нумерации версий и почему именно эта структура хранилища является лучшей. Вот слайды презентации.
Также есть мой ответ на вопрос "Несколько репозиториев SVN против репозитория одной компании". Это может быть полезно, если вы решите этот вопрос структурирования репозитория в своем вопросе.
Поскольку у нас есть все артефакты и конструкции в одном дереве, мы имеем что-то вроде:
Хобот
- Планирование и отслеживание
- Req
- дизайн
- строительство
- мусорное ведро
- База данных
- Lib
- Источник
развертывание
- контроль качества
- Массачусетс
Как насчет внешних зависимостей, таких как AJAXTookit или какое-либо другое стороннее расширение, которое используется в нескольких проектах?
Исходный контроль предназначен для исходного кода, а не для двоичных файлов. Храните любые сторонние сборки / банки в отдельном хранилище. Если вы работаете в мире Java, попробуйте что-то вроде Maven или Ivy. Для проектов.Net простой общий диск может работать хорошо, если у вас есть приличные политики относительно его структуры и обновления.
Я думаю, что политики и процедуры SCM, которые принимает команда, будут сильно зависеть от процесса разработки, который они используют. Если у вас есть команда из 50 человек, в которой несколько человек работают над серьезными изменениями одновременно, а выпуски происходят только раз в 6 месяцев, для каждого имеет смысл иметь свою собственную ветку, где он может работать в изоляции и объединять изменения только из другие люди, когда он хочет их. С другой стороны, если вы команда из 5 человек, все сидят в одной комнате, имеет смысл разветвляться гораздо реже.
Предполагая, что вы работаете в небольшой команде, где общение и совместная работа хороши, а выпуски случаются часто, бессмысленно переходить в IMO. В одном проекте мы просто свернули номер редакции SVN в номер версии продукта для всех наших выпусков, и мы даже не пометили тегами. В редких случаях, когда в prod была обнаружена критическая ошибка, мы просто переходили прямо из выпущенной ревизии. Но большую часть времени мы просто исправляли ошибку в ветке и освобождали от ствола в конце недели, как и планировалось. Если ваши релизы достаточно часты, вы почти никогда не столкнетесь с ошибкой, которая не может дождаться следующего официального релиза.
Я работал над другими проектами, в которых нам никогда не удавалось сойти с рук, но благодаря легкому процессу разработки и низкой церемонии мы смогли очень эффективно использовать упрощенную политику контроля версий.
Я также упомяну, что все, что я написал, исходит из корпоративного ИТ-контекста, где существует только один производственный экземпляр данной базы кода. Если бы я работал над продуктом, который был развернут на 100 различных сайтах клиентов, методы ветвления и тегирования должны были бы быть немного более напряженными, чтобы управлять всеми независимыми циклами обновления во всех экземплярах.
Мы мигрировали из плохого мира VSS с одним гигантским хранилищем (более 4G), прежде чем переключиться на SVN. Я действительно боролся с тем, как настроить новый репозиторий для нашей компании. Наша компания очень "старой" школы. Трудно добиться перемен. Я один из младших разработчиков и мне 45 лет! Я являюсь частью корпоративной команды разработчиков, которая работает над программами для ряда отделов нашей компании. Во всяком случае, я настроил наши каталоги, как это
+ devroot
+--Dept1
+--Dept1Proj1
+--Dept2Proj2
+--Dept2
+--Dept2Proj1
+--Tools
+--Purchase3rdPartyTools
+--NLog
+--CustomBuiltLibrary
Я хотел включить возможность ветвления, но, честно говоря, это слишком много на данный момент. Несколько вещей, которые мы все еще боремся с использованием этой схемы.
- Трудно решить производственные проблемы, если вы работаете над серьезным обновлением продукта (т. Е. Потому что мы не делаем ветвления)
- Сложно управлять концепцией продвижения из "Dev" в "Prod". (Даже не спрашивайте о продвижении в QA)