Какие есть варианты при работе с подмодулями Git, из которых делаются коммиты?
На работе мы работаем над дюжиной пакетов Java OSGi, каждый из которых имеет свой собственный репозиторий git. Все пакеты будут, в конечном счете, довольно независимы друг от друга, что оправдывает отдельные репозитории - хотя сейчас мы все еще часто модифицируем несколько из них одновременно.
Когда мы делаем релиз продукта (который состоит из всех пакетов), в каждом пакете создается новая ветвь, что немного болезненно. Таким образом, мы думали об использовании git-submodule для облегчения боли (что-то вроде git submodule foreach <cmd>
).
Итак, наша желаемая установка будет мастер-проектом Product
и подмодули для каждого пакета:
Project/
BundleA/
BundleB/
BundleC/
Теперь я потратил несколько часов на чтение всего, что мог найти о подмодулях, и я понял, что если я изменю вещи в BundleA
Я должен совершить в BundleA
, нажмите, затем замените подмодуль в Project
и нажмите еще раз.
Это явно звучит так, будто это был не тот способ, которым git-submodule был разработан для использования в первую очередь. Это против лучших методов использовать это как это? Или это звучит как случай, когда альтернатива будет предпочтительнее?
- использование git-субмодуля
- используя существующую "git wrapper":
- написать свои собственные простые bash-скрипты для пакетной обработки пакетов OSGi
Любые другие предложения приветствуются.
2 ответа
Если вам не нужно отслеживать, что делает подпроект в суперпроекте (жесткое связывание), тогда я рекомендую вам держаться подальше от git-подмодулей.
gitslave (http://gitslave.sf.net) - это, по сути, большой foreach вокруг каждого из подпроектов с файлом конфигурации в суперпроекте, в котором перечисляются подпроекты. Есть много наворотов, которые делают его более удобным, но если ваша цель - запустить одну и ту же команду в суперпроекте (необязательно) и во всех подпроектах, gitslave будет примерно таким же удобным, как вы собираетесь его найти.
Например, создать новую ветку в gitslave:
gits checkout -b newbr
Затем ваш суперпроект и все подпроекты создадут новую ветвь и перейдут на нее. В общем, если вы хотите запустить команду gits на всех элементах суперпроекта, просто измените команду "git" на "gits".
Теперь я потратил несколько часов, читая все, что мог найти о подмодулях, и я понял, что если я изменю вещи в BundleA, мне придется зафиксировать в BundleA, нажать, затем зафиксировать изменение подмодуля в Project и снова нажать.
Это явно звучит так, будто это был не тот способ, которым git-submodule был разработан для использования в первую очередь. Это против лучших методов использовать это как это?
Я думаю, что именно так должны использоваться субмодули, я боюсь. Хотя, возможно, предполагается, что вы обычно фиксируете новую версию в основном проекте относительно редко, поскольку вы строго утверждаете, что эта версия подмодуля правильно работает с этой версией основного проекта. Текущий дизайн системы субмодулей довольно ограничен в том, что она может делать, поскольку основной проект знает только о субмодуле:
- То, что должно быть в подмодуле, должно храниться в дереве вместо хэша большого двоичного объекта или дерева
- URL-адрес по умолчанию для хранилища, которое (должно) содержать этот коммит, хранящийся в
.gitmodules
и установить в конфиге при инициализации субмодуля
... и когда вы работаете в субмодуле, это похоже на работу в автономном репозитории, независимо от того, есть ли там супер-проект или нет.
Из способов упрощения этого процесса, о которых вы упомянули, стоит пояснить, что в репо фактически не используются субмодули - это альтернативная система. Это также относится и к git-slave, что многие пользователи Stack Overflow рекомендуют.
Лично я работаю над проектом, в основном репозитории которого есть 24 подмодуля, и у нас все хорошо, всего лишь полезный скрипт, который упрощает процесс фиксации новой версии подмодуля и обеспечивает его правильную передачу.
Еще одна (не подмодульная) альтернатива, на которую вы, возможно, захотите взглянуть, это git-subtree, которую не следует путать со стратегией слияния поддеревьев.