158

.gitmodules这是我的文件的部分内容:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

但是,.git/config只包含第一个:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

第二个子模块 ( external/pyfacebook) 是由另一个开发人员在功能分支中添加的。我现在继承了开发,并检查了功能分支。但是,Git 不会为我拉取子模块。我试过了:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • 从中删除所有子模块定义.git/config并运行git submodule init. 它只复制先前存在的子模块并忽略新的子模块。
  • .git/config手动输入新的子模块定义并运行git submodule update. 只有以前存在的子模块才需要更新。

在各种组合中,但 git 根本不会.git/config根据 的新内容进行更新.gitmodules,也不会创建external/pyfacebook文件夹并拉取子模块的内容。

我错过了什么?是否真的需要手动干预(手动添加子模块条目.git/config),为什么?

编辑:手动干预不起作用。手动添加新的子模块条目.git/config不会做任何事情。新的子模块被忽略。

4

21 回答 21

124

我遇到了同样的问题 - 结果证明 .gitmodules 文件已提交,但实际的子模块提交(即子模块的提交 ID 的记录)没有。

手动添加它似乎可以解决问题 - 例如:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(即使没有从 .git/config 或 .gitmodules 中删除任何内容。)

然后提交它以正确记录ID。

为这个工作答案添加一些进一步的评论:如果 git submodule init 或 git submodule update 不起作用,那么如上所述 git submodule add url 应该可以解决问题。可以通过以下方式交叉检查

 git config --list

并且应该获得您想要提取 git config --list 命令结果的子模块的条目。如果配置结果中有你的子模块条目,那么现在通常的 git submodule update --init 应该拉你的子模块。要测试此步骤,您可以手动重命名子模块,然后更新子模块。

 mv yourmodulename yourmodulename-temp
 git submodule update --init

要了解子模块中是否有本地更改,可以通过 git status -u (如果您想查看子模块中的更改)或 git status --ignore-submodules (如果您不想查看更改子模块)。

于 2012-01-28T23:58:04.800 回答
90

git 版本 2.7.4。此命令更新本地代码 git submodule update --init --force --remote

于 2016-11-21T11:15:49.617 回答
20

有同样的问题,当 git 忽略initupdate命令时,什么都不做。

怎么修

  1. 您的子模块文件夹应提交到 git repo
  2. 它不应该在 .gitignore

如果满足这些要求,它将起作用。否则,所有命令将在没有任何消息和结果的情况下执行。

如果你做了所有这些,它仍然不起作用:

  1. 手动添加子模块,例如git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. 提交并推送所有文件 -.gitmodules以及您的模块文件夹(注意,文件夹的内容不会提交)
  5. 删除本地 git repo
  6. 克隆一个新的
  7. 确保.git/config还没有任何子模块
  8. 现在,git submodule init- 你会看到一个模块注册的消息
  9. git submodule update- 将获取模块
  10. 现在看看,.git/config你会发现注册的子模块
于 2015-10-27T13:45:01.807 回答
10

我遇到了同样的问题,但上述解决方案都没有帮助。.gitmodules 和 .git/config 中的条目是正确的,但该命令git submodules update --init --recursive什么也没做。我还删除了子模块目录并运行git submodules update --init --recursive并取回了子模块目录,但提交与以前完全相同。

我在这个页面上找到了答案。命令是:git submodule update --remote

于 2019-06-21T13:44:20.297 回答
10

认为手动设置.gitmodules就足够了是错误的

撰写本文时我的本地人git version 2.22.0

所以我来到这个线程想知道为什么不git submodule init工作;我设置了.gitmodules文件并继续做git submodule init......

重要的

  1. git submodule add company/project.git includes/project必需的(第一次添加模块时),这将:

    • 添加配置到.git/config
    • 更新.gitmodules文件
    • 跟踪子模块位置(includes/project在本例中)。
  2. 必须在添加子模块后git commit,这将提交.gitmodules和跟踪的子模块位置。

再次克隆项目时,它将具有.gitmodules空的子模块目录(例如includes/project在此示例中)。此时.git/config还没有子模块配置,直到git submodule init运行,记住这仅有效,因为在主 git 存储库中跟踪.gitmodulesAND 。includes/project

另请参阅:

于 2019-06-12T05:33:37.010 回答
9

答案中(也)似乎有很多混乱。

git submodule init不打算在 .git/config (来自 .gitmodules)中神奇地生成东西它的目的是在克隆父项目之后在一个完全空的子目录中设置一些东西,或者拉一个添加以前不存在的子模块的提交。

换句话说,您遵循一个git clone具有子模块的项目(通过克隆签出 .gitmodules 文件这一事实您会知道)git submodule update --init --recursive

您不使用(或),这不应该起作用git submodule add ...。事实上,如果一切正常,add 已经更新了适当的 .git/config。git submodule initgit submodule update --init

编辑

如果其他人添加了以前不存在的 git 子模块,并且您执行了git pull该提交,那么该子模块的目录将完全为空(当您执行新子模块的哈希应该是可见的,但前面git submodule status会有-它。)在这种情况下,您git pull还需要在后面加上一个git submodule update --init(加上--recursive当它是子模块中的子模块时),以便签出新的、以前不存在的子模块;就像在一个带有子模块的项目的初始克隆之后(显然你之前没有这些子模块)。

于 2016-12-27T17:52:31.203 回答
5

有点神奇,但今天我跑git submodule init了又 跑git submodule syncgit submodule update它开始拉我的子模块……魔法?也许!这确实是 Git 最烦人的体验之一……</p>

刮那个。我实际上是通过做它来工作的git submodule update --init --recursive。希望这可以帮助。

PS:确保您在根 git 目录中,而不是子模块的。

于 2014-05-19T01:10:13.813 回答
5

这意味着子模块没有正确设置git submodule add,必须执行命令。子模块如何工作的详细解释:

如果正确添加子模块:

如果子模块没有正确提交,并且子模块及其对应的文件夹还没有记录在索引中,那么首先 .gitmodules 文件中的每个子模块都需要单独添加 viagit submodule add才能继续。

  • 注意:正如这里提到的,Git 目前没有命令对 .gitmodules 文件中存在的多个子模块一次执行此操作。

做什么git submodule add

当带有子模块的 repo 已正确设置并且有人已经执行了git submodule add命令时,该命令执行了以下操作:

  1. 如果子模块尚不存在,则为子模块创建一个文件夹
  2. 将项目克隆为子模块
  3. 在可共享的.gitmodules 文件中设置子模块参数
  4. 在您的私有.git/config 文件中设置子模块参数
  5. 在超级项目的私有 .git/modules 文件夹中为子模块创建一个 .git 文件夹
  6. 并且:在超级项目的索引中记录每个子模块它将驻留在哪个文件夹中,以及它应该处于什么状态(子模块的哈希提交代码。)

当您克隆超级项目时,第3点和第 6点是相关的,第6点指示 agit submodule add是否已正确执行并已提交。您可以通过查看子模块应该驻留的文件夹是否已经存在并且为空来检查第6点(注意:这不需要 .keep 或 .gitignore 机制,因为这是 Git 机制的一部分。)克隆超级项目后,您还可以执行 agit submodule查看预期的子模块。

然后,您可以继续执行以下操作:

  • git submodule

    将显示树中存在的子模块及其相应的提交哈希码,可以作为初始检查以查看预期的子模块

  • git submodule init

    将 repo 的 .gitmodules 文件中的子模块参数复制到您的私有 .git/config 文件(第4点)

  • git submodule update

    将子模块克隆到由超级项目确定的提交,并在超级项目的 .git/modules/ 文件夹下创建子模块的 .git 文件夹(第 2点和第 5点)

  • git submodule update --remote

    与更新相同,但将子模块设置为远程仓库可用的分支上的最新提交,类似于之后进入每个子模块的文件夹并执行git pull

  • 或者: git submodule update --init --remote

    这是所有以上的结合。

或者,当 repo 设置正确时,您还可以git clone使用--recursiveflag 将子模块包含在 init 中,并自动对其执行更新。

于 2020-11-23T17:11:17.760 回答
4

According to the answer from Dave James Miller I can confirm that it worked for me. The important thing here was to commit the subprojects commit ID. Just to have the entry in .gitmodules was not enough.

Here is an appropriate commit:

https://github.com/dirkaholic/vagrant-php-dev-box/commit/d5f4c40bdbd80eefbb5ac6029823733f591435ae

于 2012-07-15T15:03:56.790 回答
3

我有同样的问题。

.gitmodules有子模块,但在git submodule init命令之后它不在.git/config.

原来添加子模块的开发人员也将子模块目录添加到.gitignore文件中。那是行不通的。

于 2013-01-28T03:44:56.570 回答
3

我对子模块有类似的问题。它只是不想被克隆/拉动/更新/无论如何。

尝试使用重新添加子模块时,git submodule add git@my-repo.git destination我得到以下输出:

A git directory for 'destination' is found locally with remote(s):
  origin        git@my-repo.git
If you want to reuse this local git directory instead of cloning again from
  git@my-repo.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

因此,我尝试强制执行 add 命令
git submodule add --force git@my-repo.git destination

这在我的情况下有效。

于 2017-05-31T12:18:00.190 回答
3

对我来说问题是 repo 以前的开发人员将该submodules/thing文件夹作为普通文件夹提交,这意味着当我尝试运行时git submodule add ...,它会失败并显示:'submodules/thing' already exists in the index,但是尝试更新子模块也会失败,因为它看到路径没有包含一个子模块。

要修复,我必须删除submodules/thing文件夹,提交删除,然后运行git submodule add命令将其正确添加回来:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing
于 2019-11-12T04:37:57.350 回答
2

下面的同步命令解决了这个问题:

git submodule sync
于 2020-03-03T10:34:09.557 回答
2

我今天遇到了同样的问题,并发现因为我输入了git submodule init然后我在我的.git/config:

[submodule]
   active = .

我删除了它并输入:

git submodule update --init --remote

一切都恢复正常,我的子模块照常在其子目录中更新。

于 2017-05-11T16:54:23.590 回答
2

作为记录:
我通过添加一个空存储库作为子模块来创建相同的问题。在这种情况下,子模块没有可用的参考哈希,导致原始发布者描述的错误。

提交后强制添加存储库解决了问题(如 Arvids 帖子中所示)
git submodule add --force git@my-repo.git destination

于 2018-07-19T15:36:47.967 回答
1

当我今天看到这个时,一个开发人员已经将树的一部分移动到一个新的子目录中,看起来他的 git 客户端并没有在树中记录更新的子项目规则,而是它们只是被 nuked,导致.gitmodules两者都过时位置和当前树中不再存在的子项目。

重新添加子模块,并将子模块的提交 shas 与在git show $breaking_commit_sha(搜索匹配 regexp 的行^-Subproject)中找到的内容进行比较,以根据需要进行调整。

于 2014-04-30T21:00:07.677 回答
1

和你一样,我发现 git submodule sync 没有做你期望它做的事情。只有在git submodule add再次执行显式操作后,子模块 url 才会更改。

所以,我把这个脚本放在~/bin/git-submodule-sync.rb

https://gist.github.com/frimik/5125436

而且我还在一些接收后的 git deploy 脚本上使用了相同的逻辑。

我现在需要做的就是编辑.gitmodules,然后运行这个脚本,它最终会像我想象git submodule sync的那样工作。

于 2013-03-09T19:36:53.630 回答
1

如果之前存在,则删除子模块目录及其内容(“external/pyfacebook”文件夹)git submodule add ...可能会解决问题。

于 2017-05-18T15:18:16.470 回答
1

只是分享对我有用的东西:

git clone --recurse-submodules <repository path>

这会克隆已经包含子模块的远程存储库。这意味着您不需要在克隆后运行 git submodule update 或 init。

于 2020-01-20T19:26:21.073 回答
-1
  • 从您的子模块中删除.git/config
  • 运行git submodule init命令
  • 转到您的子模块目录并运行git pull origin master

它现在应该可以工作

于 2018-12-27T08:38:20.180 回答
-1

请检查您的子模块目录。

如果其中只有一个 .git 文件,则将其删除。

现在执行git submodule update --remote --init

于 2020-09-15T10:30:08.177 回答