SVN: внешний эквивалент в Git?

177

У меня есть два SVN-проекта из другого SVN-репозитория, использующего svn: externals .

Как я могу иметь такую ​​же структуру макета хранилища в Git?

dsimard
источник
Вы должны заглянуть в подмодули Git . Это должно позволить почти точно то, что вы ищете.
foxxtrot
7
У кого-нибудь есть новый ответ на это за последние 4 года, или мир git сегодня такой же?
DougW
4
@DougW Да, у меня есть новый ответ ниже : git submoduleтеперь могу подражать svn:external(с марта 2013 года).
VonC
Для последней версии Git я бы посоветовал прочитать о подмодулях Git в официальной документации Git.
Bulki S Maslom

Ответы:

134

У Git есть два подхода, похожих, но не в точности эквивалентных svn: externals:

  • Поддерево слияния вставляет код внешнего проекта в отдельный подкаталог вашего репозитория. Это детализированный процесс настройки, который очень прост для других пользователей, поскольку он автоматически включается при извлечении или клонировании хранилища. Это может быть удобным способом включения зависимости в ваш проект.
    Изменения легко перенести из другого проекта, но их сложно отправить обратно. И если другой проект должен объединиться из вашего кода, истории проекта объединяются, и два проекта фактически становятся одним.

  • Подмодули Git ( вручную ) ссылаются на определенный коммит в репозитории другого проекта, очень похоже на svn: externals с-rаргументом. Подмодули просты в настройке, но все пользователи должны управлять подмодулями, которые не включаются автоматически в кассы (или клоны).
    Несмотря на то, что легко отправить изменения обратно в другой проект, это может вызвать проблемы в случае изменения репо. Поэтому, как правило, нецелесообразно отправлять изменения обратно в проект, который находится в активной разработке.

Павел
источник
17
К вашему сведению, теперь можно указывать конкретные версии с помощью svn: externals сейчас (начиная с 1.5 или 1.6, я полагаю?)
Нейт Парсонс
9
К вашему сведению, подмодули git могут автоматически управляться и фиксироваться. git создает файл .gitmodules, который можно / нужно зафиксировать так же, как файл .gitignore. См. [ Git-scm.com/book/en/Git-Tools-Submodules] для получения дополнительной информации.
Микийов
5
@NateParsons Всегда можно было указать точные номера редакций с помощью svn:externals. В версии 1.5 синтаксис был изменен на более гибкий формат. То, что было добавлено, было относительной адресацией URL.
Дэвид В.
@NateParsons, но возможно ли пропустить ревизии с подмодулями git ...> _>
Trejkaz
Я думаю, что невозможно подмодулировать отдельные файлы субмодуля, как с svn: externals
user1911091
38

Как я упоминал в « Обновлении новой версии подмодуля Git », вы можете добиться той же внешней функции SVN с подмодулями Git 1.8.2:

git config -f .gitmodules submodule.<path>.branch <branch>

Этого достаточно, чтобы субмодуль следовал за веткой (как в последнем коммите удаленной ветви субмодуля восходящего репо ). Все, что вам нужно сделать, это:

git submodule update --remote

Это обновит субмодуль.

Более подробная информация находится в git submoduleразделе « Отслеживание последних ».

Чтобы преобразовать существующий субмодуль в один отслеживающий ветвь : см. Все шаги в « Git submodules: укажите ветку / тег ».

VonC
источник
Можете ли вы сделать частичный заказ как с svn:externals?
nowox
@nowox Да, у вас может быть редкая проверка (git 1.7+ stackoverflow.com/a/2372044/6309 ), связанная с подмодулями ( stackoverflow.com/a/17693008/6309 )
VonC
к сожалению, все ответы, связанные с разреженной проверкой, никогда не приводят никакого примера :( Я постараюсь написать пример Gist для этого ...
nowox
Есть еще проблема с этим. Вы все еще должны получить всю историю хранилища, где вам нужна только одна небольшая часть. В моем случае это 100 КБ более 2 ГБ. Я могу, конечно, использовать, --depthно это не решает проблему.
nowox
@nowox Лучше всего задать новый вопрос, объясняющий, в чем именно заключается ваш вариант использования: я понятия не имею, является ли ваше репо объемом 2 ГБ подмодулем или основным репо с подмодулем, и что именно вам нужно извлечь из него.
VonC
3

Я автор инструмента gil (git links)

У меня есть альтернативное решение проблемы - инструмент 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 ссылку в следующем формате:

  1. Уникальное имя хранилища
  2. Относительный путь к хранилищу (начинается с пути файла .gitlinks)
  3. Git-репозиторий, который будет использоваться в команде git clone.
  4. Пустая строка или строка, начинающаяся с #, не анализируется (рассматривается как комментарий).

Наконец, вам нужно обновить репозиторий с корневым образцом:

# 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 рекурсивных субмодулей .

chronoxor
источник
1
Вы должны поместить отказ от ответственности в верхней части поста, в котором говорится, что вы автор gil.
Даниэль Камил Козар