Как структурировать хранилище, состоящее из нескольких библиотек и приложений - PullRequest
6 голосов
/ 25 января 2011

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

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

    +---------->include files
    |                ^
    |                |
library A -----> library B <----- library C <----- library D
  ^  ^                                |                ^
  |  |                                |                |
  |  +--------------------------------+                |
  |                                                    |
application 1        application 2 --------------------+
  ^
  |
script -----> configuration information

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

Я придумал следующую структуру:

trunk/
  include/
  lib/
    library A/
    library B/
    library C/
    library D/
  app/
    application 1/
    application 2/
tags/
  1.0/
    include/
    lib/
      library A/
      library B/
      library C/
      library D/
    app/
      application 1/
      application 2/
  1.1/
    include/
    lib/
      library A/
      library B/
      library C/
      library D/
    app/
      application 1/
      application 2/
  ...

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

Проблема этого решения состоит в том, что библиотеки не имеют отдельных каталогов тегов для себя, ичто я хочу только выпуск, состоящий из компонентов с тегами, и это решение не отображает, какие компоненты имеют версии тегов в выпуске.Я рассмотрел использование отдельных репозиториев, а затем создал главный репозиторий, в котором есть подкаталог релизов, в котором я связываю все необходимые компоненты с помощью `svn: externals 'и подкаталога с конкретными тегами, но разные библиотеки и включаемые файлы зависят друг от друга, и я неНе видите, как разбить код на отдельные объекты.

Есть идеи?

=============== Вопрос продолжен 28-1-2011 ===============

Хорошо, я нарисовал график того, как я планирую новый макет.Цель состоит в том, чтобы связать теги различных зависимостей с помощью метода svn: externals в одном репозитории, например, я бы установил svn: externals в trunk / projects / lib / library2 / зависимости на ^ / tags / projects / include / std /1.3.

trunk/
  projects/
    include/
      std/
    lib/
      library1/
        dependencies/
          std/ --> tags/projects/include/std/1.2
      library2/
        dependencies/
          std/ --> tags/projects/include/std/1.2
          library1/ --> tags/projects/lib/library1/1.4.3
      library3/
        dependencies/
          std/ --> tags/projects/include/std/1.3
          library1/ --> tags/projects/lib/library1/1.4
    app/
      application1/
        dependencies/
          library3/ --> tags/projects/lib/library3/1.1
      application2/
        dependencies/
          library1/ --> tags/projects/lib/library1/2.1
      application3/
        dependencies/
          std/ --> tags/projects/include/std/1.2
          library2/ --> tags/projects/lib/library2/1.5.2
    config/
      configuration1/
        dependencies/
          application1/ --> tags/projects/app/application1/2.3
      configuration2/
        dependencies/
          application1/ --> tags/projects/app/application1/1.6
      configuration2/
        dependencies/
          application2/ --> tags/projects/app/application1/1.6
tags/
  projects/
    include/
      std/
        1.2/
        1.3/
    lib/
      library1/
        1.4.3/
        1.4/
        2.1/
      library2/
        1.5.2/
      library3/
        1.1/
    app/
      application1/
        1.6/
        2.3/
branches/
  ...

Остальные вопросы:

  • Работоспособен ли этот дизайн или вы видите какие-либо серьезные недостатки?
  • Что произойдет, если я скопирую библиотеку вкаталог тегов?Это также скопирует свойство svn: externals.Это вызовет проблемы, или это поведение желательно?
  • Я мог бы указать явную ревизию для всех внешних устройств, но тег не должен изменяться в любом случае, так что каталог будет недостаточным?
  • Будет лирепозиторий, разделенный на репозиторий разработки и репозиторий, который использует svn: external, будет лучшим решением?См. Ответ «варианты использования» на вопрос В чем преимущества «svn: externals»? .

Ответы [ 2 ]

6 голосов
/ 25 января 2011

Я предлагаю вывернуть таксономию наизнанку.В subversion я предлагаю таксономию, такую ​​как:

companyname/
  include/
    trunk/
    tags/
    branches/
  libraryA/
    trunk/
    tags/
    branches/
  libraryB/
    trunk/
    tags/
    branches/
  libraryC
    trunk/
    tags/
    branches/
  libraryD/
    trunk/
    tags/
    branches/
  application1
    trunk/
    tags/
    branches/
  application2
    trunk/
    tags/
    branches/

В git я предлагаю вам создать отдельное репозиторий git для include, libraryA, libraryB, application1 и т. Д. ...

Эта структура позволит вам создавать любые зависимости между различными частями (например, ветвь в application1 может зависеть от нестабильной версии проекта libraryA, в то время как HEAD в application1 может зависеть от стабильной версии проекта libraryA),

Эта структура также хорошо работает с большинством инструментов сборки, таких как maven, rake, buildr, ant и т. Д.

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

ОБНОВЛЕНИЕ: Чтобы немного рассказать о том, как может идти рабочий цикл:

Итак, например, допустим, что мы закончили реализацию исправлений ошибок для Application1 (назовем эту версию 1.0.0).Последние и самые большие изменения проверены в application1 / trunk.Эта версия Application1 зависит от библиотеки D v0.5.0.Вы обновляете application1 / trunk / README.txt, отмечая, что эта версия зависит от libraryD v0.5.0.Возможно, что еще важнее, скрипт сборки внутри приложения / trunk знает, как извлечь библиотеку D / tags / 0.5.0.Затем создайте тег (который является просто копией транка в текущем состоянии) в application1 / tags / 1.0.0.

Теперь, скажем, проходит неделя, и другой разработчик обновляет libraryD до версии 1.3.0.Вам нужно улучшить приложение1.Итак, внесите изменения в application1 / trunk.Затем обновите application1 / trunk / README.txt, чтобы сказать, что вы теперь зависите от libraryD v1.3.0 (и, аналогично, новый скрипт сборки для application1 v1.3.0 извлечет libraryD / tags / 1.3.0).Скопируйте application1 / trunk в application1 / tags / 1.1.0.

Теперь вы всегда можете вернуться к application1 / tags / 1.0.0 при необходимости (и быть уверенным, что он будет извлекать код из libraryD / tags / 0.5.0. application / tags / 1.1.0 будет использовать libraryD версии 1.3.0.

И в subversion, и в git тег - это ссылка на набор файлов в данный момент времени. Это означает, чтотеги не занимают много места, поэтому я говорю теги рано и часто; -)

1 голос
/ 26 января 2011

Важным вопросом является то, все ли библиотеки и приложения тесно связаны в одном продукте или могут ли они жить независимо друг от друга. IMO Поместить их в один репозиторий git имеет смысл, только если все библиотеки и приложения являются одним продуктом, поскольку, кроме svn, вы не можете извлечь только часть дерева git. Когда библиотеки и приложения независимы, вы можете создать репо для каждой библиотеки / приложения и склеить их вместе с помощью подмодулей.

Подмодули Git похожи на svn extarnals, но они всегда ссылаются на конкретную ревизию цели, а не только на простой URL. Поэтому, когда вы запускаете git checkout deadbeef, вы всегда получаете состояние подмодуля с момента, когда был создан коммит deadbeef, независимо от того, кто является главой репо, на который ссылаются. Таким образом, тег git также принимает состояние каждого подмодуля, в отличие от svn с URL-адресом без ревизии.

...