Підмодулі оновлення Git рекурсивно


284

Структура мого проекту

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.


Відповіді:


609
git submodule update --recursive

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

git submodule update --init --recursive

Примітка. У деяких старих версіях Git , якщо ви використовуєте цю --initопцію, вже ініціалізовані підмодулі можуть не оновлюватися. У цьому випадку також слід запустити команду без --initопції.


1
Як щодо рекурсивного додавання підмодуля? "git submodule add FrameworkA.git" просто витягніть файли FrameworkA.
complez

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
Я також додав --рекурсивний до останнього рядка: "git submodule foreach --recursive git merge origin origin master", інакше ви можете отримати брудний підмодуль, коли сам оновив підмодуль.
Майкл Скотт Катберт

Шукали цього протягом останніх трьох годин. Дякую вам сер. Щоб додати до цього, ви також можете використовувати ці команди для здійснення, наприклад: git submodule foreach --recursive 'git commit -a | :'. Це :робить цикл незалежно від результату. Дивіться посилання stackoverflow.com/questions/19728933/… .
Новий Піджон

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
Ахмад AlMughrabi

відсутність рекурсивної опції означає, що це працює, лише якщо ваші підмодулі знову не включають підмодулі.
erikbwork

15

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

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

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

Після цього потрібно здійснити зміни:

git add . && git commit -m 'Update submodules to latest revisions'

Це, я думав, що я щось роблю не так, але ваша відповідь мені підтвердила, що git submodule update --remote my-dir/my-submoduleпрацює так само
iomv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.