Як "git clone", включаючи підмодулі?


1990

Я намагаюся поставити підмодуль у репо. Проблема полягає в тому, що коли я клоную батьківський репо, папка підмодуля повністю порожня.

Чи є спосіб зробити так, щоб 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

Відповіді:


2975

З версією 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.

З версією 1.9 Git до версії 2.12 ( -jпрапор доступний лише у версії 2.8+):

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

З версією 1.6.5 Git і пізнішої версії ви можете використовувати:

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

122
Чи є спосіб вказати цю поведінку за замовчуванням у вашому сховищі git, щоб менш обізнані клонери автоматично отримали ініціалізований підмодуль?
NHDaly

11
@NHDaly На жаль, ні. (Не те, що я знаю, принаймні.)
Mathias Bynens

6
І логічно мислячий клон git - рекурсивний також заповнить будь-які підмодулі підмодуля, правда?
jayarjo


5
@toszter: це так мудро? Що робити, якщо холдингу Repo потрібна версія підмодуля, яка не є master?
Готьє

498

Ви повинні зробити дві речі, перш ніж заповниться підмодуль:

git submodule init 
git submodule update

8
Я боявся цього ... це не має сенсу, оскільки ви перевіряєте частковий проект у такому випадку. Я розумію, що оновлення підмодуля не є автоматичними, але чому не пов'язана версія автоматично перевіряється ?? Чи є якийсь спосіб змусити це? У мене є проект із 3-х рівневими підмодулями, і здається абсурдним проходити так далеко, щоб зробити замовлення.
Марк

10
Будь ласка, прочитайте довідковуgit-submodule(1) сторінку ( kernel.org/pub/software/scm/git/docs/git-submodule.html ). Ви дізнаєтесь, що git submodule updateпідтримує приємний параметр, який називається --recursive.
Joschi

95
Чому б не зробити обох в одній команді? git submodule update --init(Дивіться також мою відповідь ).
Mathias Bynens

9
Я думаю, що краще відповісти на питання цими двома командами. Її пояснюється краще, як виконати завдання.
schmijos

6
@MathiasBynens Машина, на яку я щойно увійшов, має лише git 1.5.5.6, який, очевидно, не підтримує скорочену інструкцію, але підтримує її як дві команди.
Джек Поульсон

221

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 рекурсивно для частини init.
Див git submoduleпояснені більш.

З версією 1.6.5 git і пізнішої версії ви можете це зробити автоматично, клонувавши суперпроект з –-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) .
(Об'єднано Хуніо С Хамано - 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.


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...
Фіолет Жирафа

Якщо ви знаєте рішення, я б поставив окреме запитання, на яке ви могли б відповісти. Ось тестовий репо, що я не можу знайти іншого способу інтимувати,
Violet Giraffe

@VioletGiraffe Це відбувається тому , що ви додали і зробили .gitmodules , але не gitlink ( stackoverflow.com/a/16581096/6309 , спеціальні записи в індексі: stackoverflow.com/a/19354410/6309 ) Ось це сховище , яке робить зареєструйте належну посилання на gitlink: github.com/tiagomazzutti/antlr4dart
VonC

108

[Швидкий відповідь]

Ви можете скористатися цією командою для клонування репо з усіма підмодулями:

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

Він автоматично витягує дані підмодуля, припускаючи, що ви вже додали підмодуль до батьківського проекту.


37
Зверніть увагу , що --recurse-submodulesі --recursiveє еквівалентними псевдонімами .
Joel Purra

@SuperUberDuper у цьому випадку ви можете зробити так, git submodule update --init --recursiveяк пояснено у цій відповіді
Енріко


21

пізня відповідь

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

Оскільки я щойно провів цілу годину, переймаючись з другом: Навіть якщо у вас є права адміністратора на BitBucket, завжди клонуйте сховище ORIGINAL і використовуйте пароль того, хто є власником репо. Дратівливо дізнатися, що ви натрапили на цей мінітрап: P


Саме з цим я маю справу. Отже, ви хочете сказати, що кожен, кому потрібно розробитись у сховищі бітбукетів, що має підмодулі, повинен використовувати облікові дані творця сховища? Відбілити.
jsleuth

@jsleuth Здається так - це смокче ВЕЛИКИЙ ЧАС ... і я це знаю.
кайзер

Це звучить як помилка. Ви повідомили про це в Bitbucket?
Mathias Bynens

@MathiasBynens Ви натрапили на це питання? Це пішло півтора року, і я насправді не знаю, чи все ще так.
кайзер

4
Він не описово відповідає на питання ОП, але детально розповідає про непов'язану помилку в 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-підмодулів без нової опції --jobs, Git отримує підмодулі по черзі.

Джерело: http://www.infoq.com/news/2016/03/git28- вийшов


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.помилка
Ендер

5

Спробуйте це.

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

Якщо ви додали підмодуль у гілку, переконайтеся, що ви додали його до команди клонування.


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.