SVN: внешний эквивалент в Git?
У меня есть два SVN-проекта из другого репозитория SVN, использующего svn: externals.
Как я могу иметь такую же структуру макета хранилища в Git?
3 ответа
У Git есть два подхода, похожих на svn:externals:
Поддерево слияния вставляет код внешнего проекта в отдельный подкаталог в вашем репо. Это детализированный процесс настройки, который очень прост для других пользователей, поскольку он автоматически включается при извлечении или клонировании хранилища. Это может быть удобным способом включить зависимость в ваш проект.
Изменения легко перенести из другого проекта, но их сложно отправить обратно. И если другой проект должен слиться с вашим кодом, истории проекта сливаются, и два проекта фактически становятся одним.Подмодули Git ( руководство) ссылаются на определенный коммит в репозитории другого проекта, очень похоже на svn: externals с
-r
аргумент. Подмодули просты в настройке, но все пользователи должны управлять подмодулями, которые не включаются автоматически в проверки (или клоны).
Несмотря на то, что легко отправить изменения обратно в другой проект, это может вызвать проблемы, если репозиторий изменился. Поэтому, как правило, нецелесообразно отправлять изменения обратно в проект, который находится в активной разработке.
Как я упоминал в " Обновлении новой версии подмодуля Git", вы можете добиться той же внешней функции SVN с подмодулями Git 1.8.2:
git config -f .gitmodules submodule.<path>.branch <branch>
Этого достаточно, чтобы субмодуль следовал за веткой (как в последнем коммите удаленной ветви субмодуля восходящего репо). Все, что вам нужно сделать, это:
git submodule update --remote
Это обновит субмодуль.
Более подробная информация в "git submodule
отслеживание последних".
Чтобы преобразовать существующий субмодуль в одну отслеживающую ветку: см. Все шаги в " Git submodules: укажите ветку / тег".
У меня есть альтернативное решение проблемы - инструмент gil (git links)
Это позволяет описывать и управлять сложными зависимостями git-репозиториев.
Также он предоставляет решение проблемы зависимостей git recursive submodules.
Предположим, у вас есть следующие зависимости проекта: пример графика зависимостей репозитория git
Тогда вы можете определить .gitlinks
файл с описанием отношений с репозиториями:
# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master
# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master
# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master
Каждая строка описывает git ссылку в следующем формате:
- Уникальное имя хранилища
- Относительный путь к хранилищу (начинается с пути файла.gitlinks)
- Git-репозиторий, который будет использоваться в команде git clone.
- Пустая строка или строка, начинающаяся с #, не анализируется (рассматривается как комментарий).
Наконец, вам нужно обновить репозиторий с корневым образцом:
# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link
# The same result with a single command
gil update
В результате вы клонируете все необходимые проекты и правильно связываете их друг с другом.
Если вы хотите зафиксировать все изменения в каком-либо репозитории со всеми изменениями в дочерних связанных репозиториях, вы можете сделать это с помощью одной команды:
gil commit -a -m "Some big update"
Команды Pull, Push работают аналогично:
gil pull
gil push
Инструмент Gil (git links) поддерживает следующие команды:
usage: gil command arguments
Supported commands:
help - show this help
context - command will show the current git link context of the current directory
clone - clone all repositories that are missed in the current context
link - link all repositories that are missed in the current context
update - clone and link in a single operation
pull - pull all repositories in the current directory
push - push all repositories in the current directory
commit - commit all repositories in the current directory
Подробнее о проблеме зависимости git рекурсивных субмодулей.
Вы должны заглянуть в подмодули Git. Это должно позволить почти точно то, что вы ищете.
Для последней версии Git я бы посоветовал прочитать о подмодулях Git в официальной документации Git.