Лучшие практики для нескольких git-репозиториев

У меня есть около 20 различных хранилищ. Многие являются независимыми и компилируются как библиотеки, но некоторые другие имеют зависимости между ними. Разрешение зависимости и ветвление сложны.

Предположим, у меня есть супер-проект, который объединяет только все остальные репозитории. Он используется исключительно для запуска тестов - никаких реальных разработок здесь не происходит.

/superproject  [master, HEAD]
    /a         [master, HEAD]
    /b         [master, HEAD]
    /c         [master, HEAD]
    /...

Теперь, чтобы разработать конкретные функции или исправления для каждого из них (a), особенно один из тех, которые требуют определенных версий проектов для компиляции или запуска (b v2.0 а также c 3.0) Я должен создать новую ветку:

/superproject  [branch-a, HEAD]  <-- branch for 'a' project
    /a         [master]  <-- new commits here
    /b         [v2.0]
    /c         [v3.0]

За bможет потребоваться что-то еще, например a v0.9 а также c v3.1:

/superproject  [branch-b, HEAD]  <-- branch for 'b' project
    /a         [v0.9]   <-- older version than 'a'
    /b         [master] <-- new commits go here
    /c         [v3.1]   <-- newer version than 'a'

Это становится еще более сложным и сложным при реализации общих рабочих процессов git, включающих ветви функций, ветви исправлений, выпуски веток и т. Д. Мне посоветовали (и не рекомендовали) использовать git-submodules, git-subtreeGoogle's git-repo, git-slave, так далее.

Как я могу управлять непрерывной интеграцией для такого сложного проекта?

РЕДАКТИРОВАТЬ

Реальный вопрос в том, как запустить тесты, не издеваясь над всеми другими зависимыми проектами? Особенно, когда все проекты могут использовать разные версии. Запускать тесты Jenkins после коммитов в подмодулях git

2 ответа

Решение

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


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

Начиная с настройки вашего вопроса, вот как вы настроили запись чистых сборок в подпроектах:

cd $superproject
git init .
git add a b c etc
git commit -m "recording test state for $thistest"

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

Хотите проверить правильный коммит на пути foo?

(commit=`git rev-parse :foo`; cd foo; git checkout $commit)

Rev-parse извлекает идентификатор содержимого для foo из индекса, cd и checkout делают это.

Вот как вы найдете все свои подмодули и что нужно проверить для воссоздания поэтапной индексированной среды:

git ls-files -s | grep ^16

Проверьте, какие текущие списки индексов для подмодуля и что на самом деле проверено там:

echo $(git rev-parse :$submodule; (cd $submodule; git rev-parse HEAD))

и там вы идете. Проверьте правильные коммиты во всех ваших подмодулях?

git ls-files -s | grep ^16 | while read mode commit stage path; do
        (cd "$path"; git checkout $commit)
done

Иногда вы несете локальные патчи, которые вы хотите применить к каждой проверке:

git ls-files -s | grep ^16 | while read mode commit stage path; do
        (cd $path; git rebase $commit)
done

и так далее. Там в git submodule команды для них, но они не делают ничего, что вы не видите выше. То же самое для всего остального, вы можете перевести все, что они делают, в почти одинаковые, как указано выше.

В подмодулях нет ничего таинственного.


Непрерывная интеграция, как правило, выполняется с помощью любого из множества инструментов, я оставлю это кому-то другому.

Как автор, git slave может работать в этой ситуации. Как его использовать, будет зависеть от того, управляете ли вы репо ab а также c; под этим я подразумеваю, что вы могли бы синхронизировать стратегию ветвления между ними, чтобы ветка v2 означала одно и то же для всех. Если это правда, я настоятельно призываю git slave так как вы можете по существу рассматривать это как один большой проект.

Если бы вы не могли назначить общую стратегию ветвления и тегов, вы бы навязали одну, которая становится все ближе к облегченной версии рабочего процесса, которую jthill предложил с git submodules, В частности, вы можете иметь свое собственное отслеживание репо ab а также c и создать branch a ветвь в каждой из них, которая будет соответствовать любой правильной ветви для каждого подчиненного репо. подобно git submodules вам придется вручную обновлять каждый репо (в этом случае объединить). Тем не менее, вам не нужно делать материнский шаг, чтобы сделать коммит в суперпроекте. Использование этой техники - не тот случай, когда подчиненные проекты имеют одно и то же имя ветви, когда они занимаются собственной разработкой, но это будет работать.

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

Другие вопросы по тегам