Підмодулі оновлення 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.