如何“ git clone”包括子模块?


1988

我正在尝试将子模块放入存储库中。问题是当我克隆父仓库时,子模块文件夹完全为空。

有什么方法可以git clone parent_repo将数据实际放入子模块文件夹中吗?

例如,http://github.com/cwolves/sequelize/tree/master/lib/nodejs-mysql-native指向在外部git的子模块,但是当我结账的sequelize项目,该文件夹为空。


4
该命令将是git clone --recurse-submodules --remote-submodules(Q3 2019 Git 2.23):它将在一个命令中克隆和更新子模块。请参阅下面我编辑的答案
VonC

Answers:


2974

在Git 2.13及更高版本中,--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

在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

122
有什么方法可以将此行为指定为git存储库中的默认行为,以便通知较少的克隆程序将自动获取已初始化的子模块?
NHDaly

11
@NHDaly可悲的是,没有。(至少我不知道。)
Mathias Bynens

6
从逻辑上讲git clone --recursive还将填充子模块的任何子模块,对吗?
jayarjo


5
@toszter:这样明智吗?如果保留存储库需要的子模块版本不是 master
Gauthier 2015年

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 2010年

94
为什么不只在一个命令中同时执行它们呢?git submodule update --init(另请参阅我的回答)。
Mathias Bynens 2010年

9
我认为最好用这两个命令来回答这个问题。它更好地说明了如何完成任务。
schmijos

6
@MathiasBynens我刚登录的机器只有git 1.5.5.6,它显然不支持缩短的指令,但确实支持两个命令。
Jack Poulson

220

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指定,则此命令将递归到已注册的子模块中,并更新其中的任何嵌套子模块。

有关init部分,请参见递归使用git子模块
参见git submodule说明

在git 1.6.5及更高版本中,您可以通过以下–-recursive选项克隆超级项目来自动执行此操作:

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

使用git 2.8更新2016:请参阅“ 如何使用来加速/并行化git子模块的下载git clone --recursive

您可以并行使用多个线程来启动获取子模块。
为实例:

git fetch --recurse-submodules -j2

更好的是,使用Git 2.23(2019年第三季度),您可以在一个命令中将子模块克隆并签出到其跟踪分支!

参见Ben Avison(提交4c69101(2019年5月19日(由Junio C Hamano合并--commit 9476094中,2019年6月17日)bavison
gitster

clone:添加--remote-submodules标志

在使用时git clone --recurse-submodules,对于希望子模块在其远程跟踪分支上而不是在超级项目中记录的SHA-1检出的任何用例,以前都没有办法将--remote切换传递给隐式git submodule update命令。

此补丁纠正了这种情况。
实际上--no-fetchgit submodule update它也基于子模块刚刚被克隆的原因而传递,因此再次从远程进行获取只会减慢速度。

这意味着:

--[no-]remote-submodules:

克隆的所有子模块将使用子模块的远程跟踪分支的状态来更新子模块,而不是超级项目的已记录SHA-1。等同于传递--remotegit 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-submodulessubmodule 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等效的别名
2013年

在这种情况下,@ SuperUberDuper可以git submodule update --init --recursive按照此答案中的
Enrico


21

迟来的答案

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

正如我整整花了一个小时摆弄一个朋友一样:即使您对BitBucket拥有管理员权限,也请始终克隆ORIGINAL存储库并使用拥有该存储库的密码。烦人的发现您遇到了这个陷阱:P


那正是我要处理的。那么,您是说需要在具有子模块的Bitbucket存储库上进行开发的任何人都必须使用存储库创建者的凭据吗?布莱克
jsleuth

@jsleuth似乎如此-很糟糕...我知道。
凯撒

听起来像个错误。您向Bitbucket报告了吗?
Mathias Bynens 2014年

@MathiasBynens您是否偶然发现了这个问题?一年半之后,我实际上不知道是否仍然如此。
kaiser 2014年

4
它没有描述性地回答OP的问题,但是详细介绍了Bitbucket中一个不相关的错误;顺便说一句,可以简称为“使用SSH密钥身份验证”。
Treffynnon

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"


11

子模块并行获取旨在通过一次启用多个存储库来减少获取存储库及其所有相关子模块所需的时间。这可以通过使用新的--jobs选项来完成,例如:

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

根据Git小组的说法,这可以大大加快更新包含许多子模块的存储库的速度。在不使用新的--jobs选项的情况下使用--recurse-submodules时,Git将一一读取子模块。

资料来源:http : //www.infoq.com/news/2016/03/git28-released


8

我对GitHub存储库有同样的问题。我的帐户缺少SSH密钥。这个过程是

  1. 生成SSH密钥
  2. 向您的GitHub帐户添加新的SSH密钥

然后,您可以使用子模块(git clone --recursive YOUR-GIT-REPO-URL)克隆存储库

要么

运行git submodule initgit submodule update在已克隆的存储库中获取子模块。


是的,那是Permission denied (publickey). fatal: Could not read from remote repository.错误的
Ender

5

尝试这个。

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

如果已将子模块添加到分支中,请确保将其添加到clone命令。


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.