Структура проектов в системе контроля версий

Я знаю, что существует как минимум 10 различных способов структурировать проект в системе контроля версий. Мне любопытно, какие методы используются и какие работают для вас. Я работал с SVN, TFS и, к сожалению, с VSS. Я видел, как управление версиями реализовано очень плохо и нормально, но никогда не было отличным.

Вот обзор того, что я видел.

Этот пример основан на SVN, но применим к большинству VCS (не столько к распределенному контролю версий).

  1. ветвление отдельных проектов, которые являются частью site / Division / web / projectName / vb / src / [trunk | branch | tags]

  2. разветвить весь сайт, в случае, который я видел, был разветвлен весь сайт, за исключением основных компонентов. / подразделение / [ствол | ветви | теги] / web / имя проекта / vb / src /

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


person Greg Ogle    schedule 19.08.2008    source источник
comment
Добавьте, пожалуйста, метку "svn", что сбивает с толку пользователей git.   -  person hhh    schedule 07.07.2012
comment
@hhh Я добавил комментарий о распределенном управлении версиями (DVC). Может быть, кому-то будет полезен ответ о структуре в DVC?   -  person Greg Ogle    schedule 18.07.2012


Ответы (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, поскольку он определяет структуру. Многие структуры хороши, пока вы их придерживаетесь.

person Boris Terzic    schedule 19.08.2008
comment
Существует ли что-то вроде maven для .NET? Мне не удалось ничего раскопать. - person whaley; 15.06.2009
comment
NMaven специально нацелен на .NET (codeplex.com/nmaven), сам не использовал его. На работе у нас есть код .NET, созданный с использованием обычного Maven и некоторых подключаемых модулей Visual Studio. - person Boris Terzic; 16.06.2009
comment
Похоже, хорошее начало, что мы запускаем новый проект со структурой, похожей на вашу :) Из любопытства, у вас есть общий родительский pom? Если да, то размещаете ли вы родительский pom в каталоге модулей или как фактический каталог внутри модулей? - person aberrant80; 23.06.2009
comment
У нас есть иерархия родительских модулей, и мы обращаемся с ними так же, как с модулями: каждый из них имеет свой собственный каталог модулей внутри модулей. Начиная с Maven2, это, наконец, чисто возможно, поскольку родительские помы наследуются из репозитория. В Maven1 вам действительно нужно использовать относительные пути, и это становится неприятно. - person Boris Terzic; 24.06.2009
comment
Спасибо: D Еще один вопрос, если не возражаете. Прямо сейчас нам пришлось переименовать модули (неподходящие начальные имена), и у нас есть небольшой спор. Если, скажем, ваш trunk / modules / m1 необходимо переименовать в trunk / modules / m10, считаете ли вы, что теги / modules / m1 следует переименовать в tags / modules / m10 или следует сохранить теги / modules / m1 и создать новый теги / модули / м10 быть созданы? - person aberrant80; 24.06.2009
comment
Учитывая, что вы помечаете так, чтобы сборка воспроизводилась, и учитывая, что если вы отметили, вы, вероятно, уже выпустили артефакты со старым именем, я бы создал новую папку тегов m10 рядом со старым. В нашем случае старые модули иначе имели бы идентификаторы артефактов, отличные от имен их каталогов модулей, и это было бы не интуитивно понятно. - person Boris Terzic; 25.06.2009
comment
Просто примечание, NMaven был на пенсии, а NPanday - это новое имя, которое все еще находится в инкубаторе. - person Greg Domjan; 25.05.2012
comment
Скептически относится к тому, является ли Maven просто беспорядком, более здесь. - person hhh; 29.06.2012

Пример для SVN:

багажник/

филиал/

теги /

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

Каждый раз, когда вам нужно создать новую функцию, вносите изменения в дизайн, что угодно, ветку. Отметьте эту ветку в начале. Затем, когда вы закончите с веткой, отметьте ее в конце. Это помогает слиться обратно в ствол.

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

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

Изменить: Для сторонних материалов это зависит. Если мне удастся этого избежать, у меня его нет в системе контроля версий. Я храню его в каталоге вне системы управления версиями и включаю оттуда. Для таких вещей, как jquery, я оставляю его под контролем источника. Причина в том, что это упрощает мой сценарий для нажатия. Я могу просто сделать svn export и rsync.

person mk.    schedule 19.08.2008

В своих проектах я всегда использую эту структуру.

  • trunk
    • config
    • документы
    • sql
      • initial
      • обновления
    • src
      • app
      • контрольная работа
    • thirdparty
      • lib
      • инструменты
  • теги
  • ветви
  • config - используется для хранения шаблонов конфигурации моего приложения. В процессе сборки я беру эти шаблоны и заменяю заполнители токенов фактическими значениями в зависимости от того, какую конфигурацию я создаю для сборки.
  • docs - Здесь размещается любая документация по приложению.
  • sql - я разбиваю свои sql-скрипты на два каталога. Один для начальной настройки базы данных, когда вы начинаете заново, а другой - для моих сценариев обновления, которые запускаются в зависимости от номера версии базы данных.
  • src - Исходные файлы приложения. Здесь я разбиваю исходные файлы на основе приложений и тестов.
  • третья сторона - сюда я помещаю свои сторонние библиотеки, на которые я ссылаюсь в своем приложении и которые недоступны в GAC. Я разделил их на основе библиотеки и инструментов. Каталог lib содержит библиотеки, которые необходимо включить в фактическое приложение. Каталог инструментов содержит библиотеки, на которые ссылается мое приложение, но они используются только для запуска модульных тестов и компиляции приложения.

Мой файл решения помещается прямо в основной каталог вместе с моими файлами сборки.

person Dale Ragan    schedule 19.08.2008
comment
как ты разветвляешься? если вы разветвляете только папку src, как вы обрабатываете свою ветку, указывающую на более старую версию третьей стороны / lib? - person wal; 28.08.2011

Я понимаю логику отказа от размещения двоичных файлов в репозитории, но я думаю, что это дает огромное преимущество. Если вы хотите получить конкретную ревизию из прошлого (обычно это более старый тег), мне нравится иметь все, что мне нужно, из svn checkout. Конечно, это не включает Visual Studio или .NET framework, но наличие правильной версии nant, nunit, log4net и т. Д. Позволяет действительно легко перейти от оформления заказа к сборке. Таким образом, начать работу так же просто, как "svn co project", за которым следует "nant build".

Единственное, что мы делаем, - это помещаем двоичные файлы ThirdParty в отдельное дерево и используем svn: external, чтобы получить нужную нам версию. Чтобы упростить жизнь, у нас будет папка для каждой использованной версии. Например, мы можем добавить в текущий проект папку ThirdParty / Castle / v1.0.3. Таким образом, все необходимое для сборки / тестирования продукта находится внутри или ниже корня проекта. По нашему опыту, компромисс с дисковым пространством того стоит.

person denis phillips    schedule 19.08.2008

Поскольку все артефакты и конструкции находятся в одном дереве, мы получаем что-то вроде:

  • Багажник

    • Planning&Tracking
    • Req
    • Дизайн
    • Construction
      • Bin
      • База данных
      • Lib
      • Источник
  • Развертывать

  • QA
  • MA
person Mariano    schedule 16.09.2008
comment
Почему это было снижено? Похоже на приличную структуру, даже если это не одна из стандартных версий, которые вы видите. - person Nathan Palmer; 05.09.2009

Я предпочитаю мелкозернистые, очень организованные, автономные, структурированные репозитории. Существует диаграмма, иллюстрирующая общий (идеальный) подход к процессу обслуживания репозитория. . Например, моя первоначальная структура репозитория (должна быть у каждого репозитория проекта):

/project
    /trunk
    /tags
        /builds
            /PA
            /A
            /B
        /releases
            /AR
            /BR
            /RC
            /ST
    /branches
        /experimental
        /maintenance
            /versions
            /platforms
        /releases

PA означает пре-альфа A означает альфа B означает бета AR означает альфа-версия BR означает бета -release RC означает релиз-кандидат ST означает стабильный

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

  • Теги в папке builds имеют номер версии, соответствующий шаблону N.x.K, где N и K - целые числа. Примеры: 1.x.0, 5.x.1, 10.x.33.
  • Теги в папке Release имеют номер версии, соответствующий шаблону N.M.K, где N, M и K - целые числа. Примеры: 1.0.0, 5.3.1, 10.22.33.

Недавно я разработал тренинг, посвященный управлению конфигурацией программного обеспечения, в котором я описываю подход к нумерации версий и почему именно эта структура репозитория является лучшей. Вот слайды презентации.

Также есть мой ответ на вопрос о 'Несколько репозиториев SVN против репозитория одной компании'. Это может быть полезно, если вы затронете этот аспект структурирования репозитория в своем вопросе.

person altern    schedule 19.01.2012
comment
Не могли бы вы обновить ссылку на диаграмму в первом абзаце? - person FvD; 22.06.2013

Я думаю, что политики и процедуры SCM, которые принимает команда, будут сильно зависеть от процесса разработки, который они используют. Если у вас есть команда из 50 человек, в которой несколько человек работают над важными изменениями одновременно, а выпуски выпускаются только каждые 6 месяцев, для каждого имеет смысл иметь свою собственную ветку, где он может работать изолированно и объединять только изменения из другие люди, когда он хочет их. С другой стороны, если вы команда из 5 человек, которые сидят в одной комнате, имеет смысл разветвляться гораздо реже.

Предполагая, что вы работаете в небольшой команде, где хорошее общение и сотрудничество и частые выпуски, нет смысла когда-либо разветвлять IMO. В одном проекте мы просто добавили номер версии SVN в номер версии продукта для всех наших выпусков и даже не пометили. В тех редких случаях, когда в продукте обнаруживалась критическая ошибка, мы просто выполняли переход прямо из выпущенной ревизии. Но в большинстве случаев мы просто исправляли ошибку в ветке и выпускали ее из основной ветки в конце недели, как и планировалось. Если ваши выпуски достаточно часты, вы почти никогда не столкнетесь с ошибкой, которая не может дождаться следующего официального выпуска.

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

Я также упомяну, что все, что я написал, исходит из корпоративного ИТ-контекста, где есть только один производственный экземпляр данной базы кода. Если бы я работал над продуктом, который был развернут на 100 различных сайтах клиентов, методы ветвления и тегирования должны были бы быть немного более напряженными, чтобы управлять всеми независимыми циклами обновления во всех экземплярах.

person Mike Deck    schedule 19.08.2008

А как насчет внешних зависимостей, таких как AJAXTookit или какое-либо другое стороннее расширение, которое используется в нескольких проектах?

Контроль версий предназначен для исходного кода, а не для двоичных файлов. Храните любые сторонние сборки / jar-файлы в отдельном репозитории. Если вы работаете в мире Java, попробуйте что-нибудь вроде Maven или Ivy. Для проектов .Net простой общий диск может работать хорошо, если у вас есть приличная политика в отношении того, как он структурирован и обновляется.

person Mike Deck    schedule 19.08.2008

Мы мигрировали из плохого мира VSS с одним гигантским репозиторием (через 4G) перед тем, как перейти на SVN. Мне было очень сложно создать новый репозиторий для нашей компании. Наша компания очень "старой" школы. Сложно добиться перемен. Я один из молодых разработчиков, мне 45! Я являюсь частью группы корпоративных разработчиков, которая работает над программами для ряда отделов нашей компании. В любом случае я настроил наши каталоги вот так

+ devroot
    +--Dept1
        +--Dept1Proj1
        +--Dept2Proj2
    +--Dept2
        +--Dept2Proj1
    +--Tools
        +--Purchase3rdPartyTools
        +--NLog
        +--CustomBuiltLibrary

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

  • Трудно исправить производственные проблемы, если вы работаете над крупным обновлением продукта (т. Е. Потому, что мы не делаем ветвления)
  • Трудно управлять концепцией продвижения от «Dev» к «Prod». (Даже не спрашивайте о продвижении в QA)
person Monroecheeseman    schedule 20.08.2008