Как «git clone», включая подмодули?

1996

Я пытаюсь поместить субмодуль в репо. Проблема в том, что когда я клонирую родительский репозиторий, папка субмодуля полностью пуста.

Есть ли способ сделать так, чтобы git clone parent_repoданные фактически помещались в папку субмодуля?

Например, http://github.com/cwolves/sequelize/tree/master/lib/ , nodejs-mysql-nativeуказывает на внешний мерзавца подмодуль, но когда я проверка на sequelizeпроект, что папка пуста.

отметка
источник
4
Эта команда будет git clone --recurse-submodules --remote-submodules(Q3 2019 Git 2.23): она будет клонировать и обновлять подмодули в одной команде. Смотрите мой отредактированный ответ ниже .
VonC

Ответы:

2978

С версией 2.13 Git и выше, --recurse-submodulesможно использовать вместо --recursive:

git clone --recurse-submodules -j8 git://github.com/foo/bar.git
cd bar

Примечание редактора: -j8это дополнительная оптимизация производительности, которая стала доступной в версии 2.8 и позволяет одновременно получать до 8 субмодулей одновременно - см man git-clone.

С Git версии 1.9 до версии 2.12 ( -jфлаг доступен только в версии 2.8+):

git clone --recursive -j8 git://github.com/foo/bar.git
cd bar

С Git версии 1.6.5 и выше вы можете использовать:

git clone --recursive git://github.com/foo/bar.git
cd bar

Для уже клонированных репозиториев или более старых версий Git используйте:

git clone git://github.com/foo/bar.git
cd bar
git submodule update --init --recursive
Матиас Биненс
источник
124
Есть ли способ указать это поведение по умолчанию в вашем git-репозитории, чтобы менее информированные клонеры автоматически получали инициализированный подмодуль?
NHDaly
11
@NHDaly К сожалению, нет. (Не то, что я знаю, по крайней мере.)
Матиас Биненс
6
И логически мыслящий git clone --recursive также заполняет любые подмодули подмодуля, верно?
Джаярджо
3
@NHDaly, похоже, нет: stackoverflow.com/questions/4251940/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
5
@toszter: это так мудро? Что делать, если для репо-холдинга нужна версия подмодуля, которой нет master ?
Готье
499

Вы должны сделать две вещи перед заполнением подмодуля:

git submodule init 
git submodule update
LiraNuna
источник
8
Я боялся этого ... это не имеет никакого смысла, так как вы проверяете частичный проект в этом случае. Я понимаю, что обновления подмодулей не являются автоматическими, но почему связанная версия не проверяется автоматически? Есть ли способ заставить его? У меня есть проект с 3-мя уровнями субмодулей, и кажется абсурдным проходить через это далеко, только чтобы оформить заказ.
Марк
11
Пожалуйста, прочтите git-submodule(1)страницу руководства ( kernel.org/pub/software/scm/git/docs/git-submodule.html ). Вы узнаете, что git submodule updateподдерживает хороший параметр с именем --recursive.
Йоси
95
Почему бы просто не сделать их обоих в одной команде? git submodule update --init(Также см. Мой ответ ).
Матиас Биненс
9
Я думаю, что лучше ответить на вопрос этими двумя командами. Это объясняет лучше, как выполнить задачу.
schmijos
6
@MathiasBynens На компьютере, в который я только что вошел, есть git 1.5.5.6, который, очевидно, не поддерживает сокращенную инструкцию, но поддерживает ее как две команды.
Джек Полсон,
225

Git 2.23 (Q3 2019): если вы хотите клонировать и обновить подмодули до последней версии:

git clone --recurse-submodules --remote-submodules

Если вы просто хотите клонировать их на записанном SHA1:

git clone --recurse-submodules

См. ниже.


Оригинальный ответ 2010

Как упоминает joschi в комментариях, git submoduleтеперь поддерживает эту --recursiveопцию (Git1.6.5 и более).

Если --recursiveуказано, эта команда будет входить в зарегистрированные подмодули и обновлять все вложенные подмодули внутри.

См. Работа с субмодулями git рекурсивно для части инициализации.
Смотрите git submoduleобъяснил больше.

В git версии 1.6.5 и выше вы можете делать это автоматически, клонируя супер-проект с –-recursiveопцией:

git clone --recursive git://github.com/mysociety/whatdotheyknow.git

Обновление 2016 года с git 2.8: см. « Как ускорить / распараллелить загрузку подмодулей git с помощью git clone --recursive? »

Вы можете начать выборку подмодуля, используя несколько потоков, параллельно.
Например:

git fetch --recurse-submodules -j2

Более того, с Git 2.23 (Q3 2019) вы можете клонировать и извлекать субмодуль в их ветку трекинга одной командой!

См. Коммит 4c69101 (19 мая 2019 г.) Бен Ависона ( bavison) .
(Слиты Junio C Hamano - gitster- в фиксации 9476094 , 17 июн 2019)

clone: добавить --remote-submodulesфлаг

При использовании git clone --recurse-submodulesранее не было никакого способа передать --remoteпереключатель неявной git submodule updateкоманде для любого случая использования, когда вы хотите, чтобы субмодули были проверены в их ветви удаленного отслеживания, а не с SHA-1, записанным в суперпроекте.

Этот патч исправляет эту ситуацию.
Это на самом деле проходит --no-fetchв git submodule updateа на том основании , что они подмодуль только что был клонирован, поэтому выборка из удаленного снова служит только замедлить ход событий.

Это значит:

--[no-]remote-submodules:

Все клонированные субмодули будут использовать состояние ветви удаленного отслеживания субмодуля для обновления субмодуля, а не записанного SHA-1 суперпроекта. Эквивалентно переходу --remoteна git submodule update.

VonC
источник
3
Так что Git потребовалось 14 лет, чтобы начать добавлять правильную поддержку для субмодулей, да. Спасибо за обновления! Что делать, если у меня уже есть клон основного репо без подмодулей и без записанного SHA1, и я хочу получить последнюю версию каждого подмодуля. Это выполнимо?
Фиолетовый Жираф
1
@VioletGiraffe Если в клонированном репозитории есть подмодули, в нем есть «записанный SHA1». И они git submodule update --init --recursive --remoteдолжны обновить их до последней версии соответствующей ветки. (напр .: stackoverflow.com/a/56981834/6309 )
VonC
1
Позвольте мне пояснить на примере: у меня есть шаблонный проект на Github, который использует подмодули, и я даже внес конкретные изменения в подмодули в это шаблонное хранилище. Но когда я создаю новый проект из этого репо, ни одна из команд, которые вы перечислили (ни, clone --recurse-submodules --remote-submodulesни submodule update --init --recursive --remote) не позволила мне на самом деле получить подпункты. Все, что я получаю, это файл .gitmodules, и я не смог найти никакого способа инициализировать подпункты, кроме как вручную клонировать их один за другим. Я хотел бы по крайней мере иметь сценарий, чтобы сделать это с submodule foreach...
Фиолетовый Жираф
Если вы знаете решение, я бы задал отдельный вопрос, на который вы могли бы ответить. Вот тестовый репозиторий, который я не могу найти для запуска, кроме как вручную: github.com/VioletGiraffe/TEST
Violet Giraffe
@VioletGiraffe Это потому, что вы добавили и зафиксировали .gitmodules, но не gitlink ( stackoverflow.com/a/16581096/6309 , специальные записи в индексе: stackoverflow.com/a/19354410/6309 ) Вот репозиторий, который делает зарегистрировать надлежащую ссылку: github.com/tiagomazzutti/antlr4dart
VonC
110

[Быстрый ответ]

Вы можете использовать эту команду для клонирования вашего репо со всеми подмодулями:

git clone --recursive YOUR-GIT-REPO-URL

Или, если вы уже клонировали проект, вы можете использовать:

git submodule init
git submodule update
Хавьер С.
источник
33

Если ваш подмодуль был добавлен в ветку, обязательно включите его в команду клонирования ...

git clone -b <branch_name> --recursive <remote> <directory>
Марс Редвин
источник
Это было больше похоже на то, что я искал ... но субмодули перечисляют свою ветвь как «отключенную». :(
AceFunk
28

Попробуй это:

git clone --recurse-submodules

Он автоматически извлекает данные субмодуля, если вы уже добавили субмодули в родительский проект.

nweiler
источник
37
Обратите внимание, что --recurse-submodulesи --recursiveявляются эквивалентными псевдонимами .
Джоэл Пурра
@SuperUberDuper в этом случае вы можете сделать, git submodule update --init --recursiveкак объяснено в этом ответе
Энрико
25

Я думаю, что вы можете пойти с 3 шага:

git clone
git submodule init
git submodule update
Мухаммад али е
источник
21

поздний ответ

// git CLONE INCLUDE-SUBMODULES ADDRESS DESTINATION-DIRECTORY
git clone --recursive https://USERNAME@bitbucket.org/USERNAME/REPO.git DESTINATION_DIR

Как я только что провел целый час, возясь с другом: даже если у вас есть права администратора на BitBucket, всегда клонируйте ОРИГИНАЛЬНЫЙ репозиторий и используйте пароль того, кто владеет репо. Раздражает, когда узнаешь, что ты наткнулся на этот минетрап: P

кайзер
источник
Это именно то, с чем я имею дело. Итак, вы говорите, что любой, кому нужно разработать репозиторий bitbucket с субмодулями, должен использовать учетные данные создателя репозитория? Blech.
jsleuth
@ jsleuth Кажется, так - это отстой БОЛЬШОЕ ВРЕМЯ ... и я это знаю.
Кайзер
Это звучит как ошибка. Вы сообщили об этом в Bitbucket?
Матиас Биненс,
@MathiasBynens Вы наткнулись на эту проблему? Прошло полтора года, и я на самом деле не знаю, так ли это до сих пор.
Кайзер
4
Он не дает описательного ответа на вопрос OP, но детализирует несвязанную ошибку в Bitbucket; что, кстати, могло бы быть сокращено до «использования аутентификации по ключу SSH».
Треффиннон,
18

Попробуйте это для включения подмодулей в репозиторий git.

git clone -b <branch_name> --recursive <remote> <directory>

или

git clone --recurse-submodules
Радхей Шьям
источник
18

Вы можете использовать --recursiveфлаг при клонировании репозитория. Этот параметр заставляет git клонировать все определенные подмодули в хранилище.

git clone --recursive git@repo.org:your_repo.git

После клонирования ветки подмодулей иногда могут быть изменены, поэтому выполните следующую команду:

git submodule foreach "git checkout master"
Ахмад Азими
источник
17

[Быстрый ответ]

После клонирования родительского репо (который содержал некоторое субмодульное репо), сделайте следующее:

git submodule update --init --recursive
Беньямин Джафари
источник
11

Параллельная выборка подмодулей направлена ​​на сокращение времени, необходимого для выборки репозиториев и всех связанных с ним подмодулей, путем одновременной выборки нескольких репозиториев. Это можно сделать с помощью новой опции --jobs, например:

git fetch --recurse-submodules --jobs=4

По словам команды Git, это может существенно ускорить обновление репозиториев, которые содержат много подмодулей. При использовании --recurse-submodules без новой опции --jobs Git будет извлекать подмодули один за другим.

Источник: http://www.infoq.com/news/2016/03/git28-released

Лонг Нгуен
источник
8

У меня была такая же проблема для репозитория GitHub. В моем аккаунте отсутствовал ключ SSH. Процесс

  1. Создать ключ SSH
  2. Добавление нового ключа SSH в вашу учетную запись GitHub

Затем вы можете клонировать репозиторий с помощью подмодулей ( git clone --recursive YOUR-GIT-REPO-URL).

или

Запустить git submodule initи git submodule updateизвлечь субмодули в уже клонированном репозитории.

Фатальная ошибка
источник
Да, это Permission denied (publickey). fatal: Could not read from remote repository.ошибка
Ender
5

Попробуй это.

git clone -b <branch_name> --recursive <remote> <directory>

Если вы добавили субмодуль в ветку, убедитесь, что вы добавили его в команду клонирования.

Himeshika96
источник
5

Если это новый проект, просто вы можете сделать так:

$ git clone --recurse-submodules https://github.com/chaconinc/YourProjectName 

Если он уже установлен, чем:

$ cd YourProjectName (for the cases you are not at right directory) 
$ git submodule init
$ git submodule update
nzrytmn
источник