Git обновляет субмодули рекурсивно

284

Мой проект struture

ProjectA
-FrameworkA (submodule)
--Twig (submodule of FrameworkA)

Как я могу рекурсивно обновлять субмодули? Я уже попробовал некоторые команды git (в корне ProjectA)

git submodule foreach git pull origin master

или

git submodule foreach --recursive git pull origin master

но не могу вытащить файлы Twig.

complez
источник
Как насчет Git-Deep ?
Мэтью Куриан

Ответы:

610
git submodule update --recursive

Вы также, вероятно, захотите использовать опцию --init, которая будет инициализировать любые неинициализированные подмодули:

git submodule update --init --recursive

Примечание: в некоторых старых версиях Git , если вы используете эту --initопцию, уже инициализированные подмодули могут не обновляться. В этом случае вы также должны запустить команду без --initопции.

drewag
источник
1
Как насчет рекурсивного добавления субмодуля? "git submodule add FrameworkA.git" просто вытащить файлы FrameworkA.
Завершить
2
Вы можете просто сделать «git submodule add blah» и затем «git submodule update --init --recursive».
drewag
Это отличается от моего пути ниже?
Уильям Энтрикен
3
@Irineau Замечание о том, что уже инициализированные подмодули не обновляются, если --initиспользуется, не соответствует моему опыту работы с Git 2.2.2. Я вижу как субмодули верхнего уровня, так и вложенные, которые уже были инициализированы, когда я использую правильную фиксацию git submodule update --init --recursive, и я думаю, что утверждение о том, что вам нужно запускать команду с или без --init, просто неверно. Если кто-либо не сможет доказать, что это такое поведение, или продемонстрировать, что оно изменилось между версиями и когда-то было правдой, я планирую полностью его отредактировать.
Марк Амери
3
@MarkAmery, я помню, что это была проблема в какой-то версии git, которую я не могу вспомнить. Я только что проверил это в 1.9.3, и проблема, кажется, больше не существует. Я обновил ответ, чтобы сослаться на расплывчатые «старые версии». Если кто-то может указать, какая версия изменила это поведение, это было бы здорово.
drewag
35

Способ, которым я пользуюсь:

git submodule update --init --recursive
git submodule foreach --recursive git fetch
git submodule foreach git merge origin master
Уильям Энтрикен
источник
6
Я работал с изменением последней строки на:git submodule foreach git pull --ff-only origin master
Гилад Пелег
2
Я также добавил бы --recursive к последней строке: «подмодуль git foreach - recursive git merge origin master», иначе вы можете получить грязный подмодуль, когда он сам обновил подмодуль.
Майкл Скотт Катберт
Искал это последние три часа. Спасибо, сэр. Чтобы добавить к этому, вы также можете использовать эти команды для совершения, например: git submodule foreach --recursive 'git commit -a | :'. Это :делает цикл независимо от результата. См. Ссылку stackoverflow.com/questions/19728933/… .
Подросток Pidgeon
17

Так как может случиться, что ветки по умолчанию ваших подмодулей нет master (что часто случается в моем случае), вот как я автоматизирую полные обновления подмодулей Git:

git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
Себастьян Варретт
источник
Я попытался добавить эту команду в свой универсальный Makefile, но все еще застрял, чтобы GNU Make игнорировала интерпретацию последовательности $ (...), несмотря на то, что она присутствует в простых кавычках. У кого-нибудь есть идея?
Себастьян Варрет
Ваша команда - это то, что мне было нужно, спасибо! Но я получаю: Entering 'Core' fatal: ambiguous argument 'origin/HEAD': unknown revision or path not in the working tree.где Core находится подмодуль
Sanandrea
Кроме того, я думаю, вам нужно выяснить этот комментарий stackoverflow.com/a/18008139/3383543
Ахмад АльМуграби
отсутствие рекурсивной опции означает, что это работает, только если ваши подмодули не содержат подмодули снова.
erikbwork
15

В недавнем Git (я использую v2.15.1), следующее рекурсивно объединит изменения подмодулей вверх по течению:

git submodule update --recursive --remote --merge

Вы можете добавить --initдля инициализации любые неинициализированные подмодули и использовать их, --rebaseесли хотите перебазировать вместо слияния.

После этого вам необходимо зафиксировать изменения:

git add . && git commit -m 'Update submodules to latest revisions'
MRTS
источник
Это, я думал, что я делаю что-то не так, но ваш ответ подтвердил мне, что git submodule update --remote my-dir/my-submoduleработает так же хорошо
IOMV