Агрегатор систем контроля версий, aka “workspace configurator”

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

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

Поэтому уже пару лет я хожу с идеей конфигуратора рабочего пространства. Буду рад, если у меня все-таки дойдут руки это сделать…

Задача

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

Требования

  • Сопоставление любой папки или файла в проекте, в том числе корневой, любой папке или файлу произвольного репозитория.
  • Единый интерфейс отслеживания изменений и управления ветками.
  • Транслирование изменений и веток в соответствующие системы контроля версий.
  • Использование различных алгоритмов отслеживания изменений, а именно:
  • Standard — в обе стороны;
  • Library — только обновления из репозитория в проект;
  • Upstream — обновления из репозитория + версионированные патчи проекта;
  • Publish — только из проекта в репозиторий;
  • Fixed — закрепление кода в определенной версии.
  • Поддержка перекрытия одной папки несколькими репозиториями.
  • Отслеживание изменений и веток конфигурации рабочего пространства в отдельном репозитории.
  • Возможность исключить установленное соответствие с репозиторием при создании ветки конфигурации.
  • Инициализация рабочего пространства из конфигурационного репозитория.

Существующие решения

Ни одно из существующих решений не удовлетворяет требованиям полностью. Наиболее близки по идеологии “google repo” и “perforce”.

svn externals

  • Только для Subversion.
  • Нет перекрытия репозиториев в одной папке.
  • Изменения и ветки внешнего репозитория отслеживаются отдельно.

git submodules

  • Только для Git.
  • Изменения и ветки внешнего репозитория отслеживаются отдельно.
  • Не отслеживаются обновления внешнего репозитория.

git subtree

  • Только для Git.
  • Поддерживается только механизм перекрытия папок.
  • По сути — набор хаков через низкоуровневый интерфейс git.

google repo

  • Только для Git.
  • По умолчанию работает по алгоритму “Standard”.
  • Отступление от стандартного алгоритма требует работы с конкретными репозиториями.
  • Идейно наиболее близкое к задаче решение.

perforce git fusion

  • Только для Git.
  • Удобный механизм управления из Perforce.
  • Интеграция с Perforce.
  • Проприетарное решение.

hg subrepository

  • Поддержка Mercurial, Subversion, Git.
  • Не отслеживаются обновления внешнего репозитория.
  • Изменения и ветки внешнего репозитория отслеживаются отдельно.
  • Не рекомендовано к использованию (feature of last resort).

Сценарии использования

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

1. Проект в Git и публикация части во внешний SVN

Андрей поддерживает в SVN большой многокомпонентный продукт Alpha.

Борис разрабатывает в Git компонент Beta продукта Alpha.

Ветка Beta/master должна публиковаться в ветку Alpha/beta, причем для папок должны выполняться следующие соответствия (слева git beta, справа svn alpha):
 /src -> /scripts/beta
 /tests -> /tests/beta
 /doc/src -> /doc/src/beta

Для решения задачи Борис создает такую конфигурацию рабочего пространства:

/ -> git beta — branch master

/src -> svn alpha — /scripts/beta — mode publish — skip branching

/tests -> svn alpha — /tests/beta — mode publish — skip branching

/doc/src -> svn alpha — /doc/src/beta — mode publish — skip branching

2. Проект в Git, внешняя библиотека в Git и собственные патчи

Андрей разрабатывает в Git проект Alpha.

Борис разрабатывает в Git библиотеку Beta.

Андрей сделал исправления в библиотеке Beta и предложил их Борису для внесения в основной репозиторий. До тех пор, пока Борис не внесет исправления в библиотеку Beta, Андрей вынужден накладывать свои исправления поверх всех обновлений библиотеки Beta.

Для решения задачи Андрей создает такую конфигурацию рабочего пространства:

/ -> git alpha

/ext/beta -> git beta — branch stable — mode upstream

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