Управление сторонними источниками и двоичными файлами, используемыми кодом под управлением источника
У меня есть большая база кода под контролем источника (была subversion, теперь git). Чтобы скомпилировать код и запустить тесты, я использую набор сторонних библиотек. Эти библиотеки можно разделить на несколько категорийL
- Только для бинарников
- Сторонние источники
- Сторонние источники + локальные модификации
В каждой библиотеке есть {Windows, Linux} X {debug, release} X {32bit, 64bit} конфигурации. Кроме того, эти библиотеки эволюционируют со временем, а разные версии моего проекта используют разные версии/сборки этих библиотек.
Мой вопрос - это лучший способ сохранить эти сторонние стороны?
Вот мой набор настроек:
- Сохранять размер исходного хранилища проекта
- Храните источник проекта в синхронизации с третьими сторонами, поэтому я всегда могу скомпилировать и запустить и старую версию
- Простота управления
- Кросс-платформа
Я пробовал и думал о нескольких решениях, но ни один из них не был удовлетворительным:
- Используйте версию script с версией для извлечения двоичных файлов с управляемого вручную FTP-сервера, который содержит все версии библиотек. Это работает, но требует тщательного управления структурой каталогов на сервере. Это ошибка, поскольку кто-то может перезаписать один из двоичных файлов с новой сборкой.
- Внешние внешние элементы SVN. В то время, когда внешние элементы SVN не могли ссылаться на определенный тег. Сегодня я использую git.
- Git subodules - вытягивает весь внешний репозиторий, который может быть огромным. В качестве альтернативы он требует управления отдельным хранилищем для каждой отдельной библиотеки. Подмодуль указывает на определенный тег, который означает, что либо я получаю все внешние, когда мне нужно только некоторые, либо я имитирую какую-то странную файловую систему в дереве git.
Мне ясно, что сторонние источники должны храниться в git в ветке поставщика, но двоичные файлы и заголовки - это разные истории.
Ответы
Ответ 1
Ярким решением для моей проблемы является git-subtree, который недавно был объединен с mainline git. Это обеспечивает справедливый баланс между моими требованиями и ограничениями платформы. Теперь у меня есть несколько репозиториев для внешних (у каждого есть ветка поставщика, а также ветка локальных изменений), и каждый репозиторий проектов принимает части этих внешних элементов в подпапки. Для того, чтобы все было организовано, я поддерживаю папки "bin" и "lib", которые содержат софт-ссылки на соответствующие файлы/папки во внешней папке externals.
git -subtree позволяет объединить поддерево из внешнего репозитория в подпапку. Подпапка может быть объединена взад и вперед с внешним репозиторием.
Плюсы/Минусы:
-
Малый репозиторий. Репозиторий не такой маленький, как я бы хотел, но он содержит только необходимые части из внешних репозиториев. Чтобы сэкономить место, я стараюсь, чтобы внешние деревья были маленькими. Я считаю, что это хорошая цена, когда я получаю простоту и надежность; так как загрузка и обновление проекта - это просто git pull, и все связанные с проектом данные содержатся в одном репозитории
-
Синхронизация Project/Externals - поскольку проект и внешние версии версируются в одном репозитории, я могу проверить любую ветвь/тег, которую я хочу, и ожидать, что он будет работать.
-
Простота - ежедневная работа прямолинейна. Обновление внешнего репозитория, создание нового или переход на другую версию внешнего может быть сложным и требует специального синтаксиса. Однако это слишком много. Лучше всего, что сначала можно добавить новый внешний проект в этот проект и только потом разделить его (используя git -subtree) в свой собственный репозиторий.
-
Кросс-платформа - Ну, это git
- Binaries - я решил избежать сохранения двоичных файлов и вместо этого предоставить Makefile. Я пришел к такому решению, поскольку некоторые из моих внешних факторов зависят от других внешних факторов, из-за чего очень сложно построить двоичный файл, который не меняется очень часто. Для некоторых внешних я сохраняю двоичные файлы из-за очень длительного времени сборки.
Состав:
/root
/External
/External1 (git-subtree from [email protected]:External1 v1.0)
/External2 (git-subtree from [email protected]:External2 v0.7)
/lib
/libExternal1.a -> ../External/External1/libExternal1.a
/libExternal2.a -> ../External/External1/libExternal2.a
/include
/External1 -> ../External/External1/include
/External2 -> ../External/External2/include
Ответ 2
Мы отправились на вариант вашего варианта 3. Вариант 1 мне кажется эквивалентным Варианту 3, но с большим количеством усилий по внедрению/тестированию с вашей стороны и, следовательно, больше возможностей ошибиться.
В конечном счете, если вы хотите иметь возможность точно воссоздать сборку, вам понадобятся ваши внешние (включая двоичные файлы), которые будут версироваться вместе с самим кодом и размещены локально. И подмодули git сделают хорошую работу для вас.
Ответ 3
Для сторонних источников, я думаю, что подмодули - это именно то, что вы ищете. Если вы не хотите требовать всю историю восходящего потока в каждом клоне, включите репозиторий вверх по течению со своим собственным, содержащим ветку ручной работы с необходимой историей. Посмотрите git commit-tree
, чтобы посмотреть, как это сделать, это легко. Идентификатор commit не будет соответствовать авторитетным восходящим потокам, но идентификатор дерева будет.
Для двоичных файлов приложение git, по-видимому, является наиболее рекомендуемым способом хранения контента, который не подходит с фокусом источника git. Я не использовал его сам, но дизайн выглядит готовым к использованию, он также поддерживает несколько независимых `репозиториев и выглядит так же удобно, как это может быть разумно.
Это не "под ключ", поэтому он действительно не соответствует вашему третьему, но он гвоздирует все остальное, и вам нужно простое использование основных инструментов.