Git不会初始化/同步/更新新的子模块


113

这是我.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不会.git/config根据的新内容进行更新.gitmodules,也不会创建external/pyfacebook文件夹并提取子模块的内容。

我想念什么?是否.git/config确实需要手动干预(将手工添加子模块条目),为什么?

编辑:手动干预不起作用。手动将新的子模块条目添加到.git/config不会执行任何操作。新的子模块将被忽略。


1
运行1.7.7.1并具有相同的问题:对.gitmodules进行更改后,“ git submodule sync”不会更新.git / config。
詹姆斯·普里茨

Answers:


35

您最近是否升级到git版本1.7.0.4?我确实遇到了类似的问题...

编辑:我解决了我的问题,但绝对不知道问题出在哪里。我从.git / config和.gitmodules中手动删除了子模块条目,并使用常规步骤重新添加了我的子模块(git子模块add等...)。


我现在的速度是1.7.2,但是我相信至少从1.6.x版本开始我就遇到了问题。
David Eyk

是的,想一想,我最终不得不按照您的描述去做(我忘了这个问题还没有解决!)。如果您不介意进一步完善答案,我会接受的。
David Eyk

9
这是git的持续弱点。即使是svn,使用外部组件也更好。
Peter DeWeese

3
我想我也遇到了这个问题(相同的步骤似乎终于解决了它)。我注意到的唯一一件事是,再次添加它,然后提交,提交说:创建模式160000 lib / jruby-swing-helpers(是吗?)
rogerdpack

1
关于“创建模式160000”,Pro Git手册说:“请注意机架条目的160000模式。这是Git中的一种特殊模式,基本上意味着您将提交记录为目录条目,而不是子目录或目录。文件。” git-scm.com/book/en/Git-Tools-Submodules
Johann

92

我有同样的问题-事实是.gitmodules文件已提交,但实际的子模块提交(即子模块的提交ID的记录)没有提交。

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

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

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

然后提交以正确记录ID。

在此工作答案中添加一些其他注释:如果git子模块init或git子模块更新不起作用,则如上所述,git子模块添加url应该可以解决问题。可以通过以下方式交叉检查

 git config --list

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

 mv yourmodulename yourmodulename-temp
 git submodule update --init

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


external/pyfacebook为了什么?
IgorGanapolsky

2
@IgorGanapolsky这是子模块的目标路径。
yuhua

这对我有所帮助,非常感谢!我可以补充一下,如果目标路径已经存在(由于尝试其他命令而对我'your/local/path' already exists and is not a valid git repo
Michael Ambrus

1
一种衬里,用于读取“ git config --list”中的条目:git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
Puggan Se,


15

有同样的问题,当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回购
  6. 克隆一个新的
  7. 确保.git/config没有任何子模块
  8. 现在,git submodule init-您将看到一条消息,说明模块已注册
  9. git submodule update -将获取模块
  10. 现在来看一下.git/config,您将找到注册的子模块

1
我相信子模块的路径可以在.gitignore中。至少我通过遵循@DaveJamesMiller的回答使它起作用。没有别的为我工作。
gebbissimo

7

答案中似乎也有很多困惑。

git submodule init打算神奇生成的东西的.git /配置(从.gitmodules)。它旨在在克隆父项目或提取包含以前不存在的子模块的提交后,在完全空的子目录中建立某些内容。

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

遵循git submodule add ...git submodule init(或git submodule update --init),这是不应该的工作。实际上,如果一切正常,添加项将已经更新相应的.git / config。

编辑

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


1
这很有趣,因为这样git help submodule说是关于init的:“ init:通过将子模块名称和url从.gitmodules复制到.git / config来初始化记录在索引中的子模块(已在其他位置添加并提交)。” 因此,听起来好像它应该完全按照您说的做不做...?是时候更新git文档了吗?
布拉德(Brad)

@brad我认为我不是这么说的-但我为该特定情况添加了说明。谢谢。
卡罗·伍德

@CarloWood知道为什么git子模块的作者决定--init获取新的子模块(而不是在上自动抓取update)是必要的吗?似乎更新您的存储库应该会抓住所有必要的东西,除非它会破坏数据。有了--init它,您就会知道可能已经创建了新的子模块,或者总是--init每次都发出新的子模块,在这种情况下,似乎应该默认将其启用。
Catskul

@Catskul显然,我不知道为什么git子模块的作者决定了什么,但是我的猜测是,“ update”保留用于更新已存在的某些内容,而“ init”用于创建(本地)新内容。在引擎盖下,两者可能相差很大,足以保证发出不同的命令。
卡罗·伍德

6

我遇到了同样的问题,但以上解决方案均无济于事。.gitmodules和.git / config中的条目是正确的,但是命令git submodules update --init --recursive没有执行任何操作。我还删除了子模块目录,并运行git submodules update --init --recursive并重新获得了子模块目录,但是提交的方式与以前完全相同。

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


2
这对我来说也是正确的解决方案。我git submodule update不是在跑步git submodule update --remote
Andrew Medlin

5

有点不可思议,但是今天我跑了,git submodule init接着又 git submodule sync跟着git submodule update,它开始拉动我的子模块...魔术?也许!这确实是Git上最烦人的经历之一。

刮一下。我实际上是通过这样做使它工作的git submodule update --init --recursive。希望这可以帮助。

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


7
不,这绝对对我没有任何帮助。
IgorGanapolsky

@IgorGanapolsky我用对我有用的方法编辑了上面的答案。让我知道它是否有效!
李维·菲盖拉

我尝试了您的新命令,但它们也不执行任何操作。
IgorGanapolsky

5

以为手动设置.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

另请参阅:



3

我有同样的问题。

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

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


2

与您发现Git子模块同步无法完成您期望的一样。仅在git submodule add再次执行显式操作后,子模块url才会更改。

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

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

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

我现在需要做的就是edit .gitmodules,然后运行此脚本,它最终将按我认为的git submodule sync方式工作。


这似乎仅在某些存储库上发生...可能是由于Git中的某些错误。很久以来,我在创建的存储库上都没有发生过这种情况,但是回想起以前,它
总是

2

今天,我遇到了同样的问题,并发现由于键入了代码,所以git submodule init我的代码中包含了以下行.git/config

[submodule]
   active = .

我删除了该内容并输入:

git submodule update --init --remote

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


2

对我来说,问题是仓库的先前开发人员将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

1

当我今天看到此消息时,开发人员已将树的一部分移到新的子目录中,看起来他的git客户端未在树中记录更新的Subproject规则,而是将它们放了下来,留下了 .gitmodules都将过时的当前树中不再存在的位置和子项目。

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


1

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


1
这是我的问题。有人将“ submodule”文件夹提交为普通文件夹,这意味着当我尝试运行“ git submodule add ...”时,它将失败,并显示:“索引中已存在“ vendor / mobx-state-tree”” ,但尝试更新子模块也将失败,因为它看到路径不包含子模块。要解决此问题,我必须删除该文件夹,提交删除,然后运行git add命令将其正确添加回去。
Venryx

1

我对子模块也有类似的问题。它只是不想被克隆/拉动/更新/任何东西。

当尝试使用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

在我看来,这是可行的。


0

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

致力于解决问题后强制添加存储库(如Arvids帖子中所述)
git submodule add --force git@my-repo.git destination



0

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

git clone --recurse-submodules <repository path>

这将克隆已经包含子模块的远程存储库。这意味着克隆后无需运行git子模块更新或init。


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.