这表示你需要先在子模块中进行提交。
这里发生了什么
子模块主要是第二个独立的 Git 存储库。在这里我们还要提一下术语说明:superproject 是非子模块 Git 存储库。这意味着我们说“在超级项目中,X 和 Y 为真”是指 X 和 Y 是存储库中的情况,不是子模块存储库。
同时,这里出现了“大部分”这个词,因为第二个子模块 Git 存储库有几个特殊条件:
-
子模块的 URL 记录在超级项目中名为 .gitmodules 的文件中。
-
子模块的提交哈希记录在超级项目的每个提交中(每个超级项目提交一个提交哈希 - 嗯,更准确地说,每个实际使用的提交该子模块)。这就像它是一个文件或目录一样保存,其名称是超级项目中到子项目的路径名。
因此,如果您的子模块在超级项目中具有路径 folder1,则超级项目中的每个特定提交都会有效地告诉 Git:“此提交预计会工作提供用户进入另一个(子模块) 存储库并将这个特定的提交哈希作为分离的 HEAD 检出。”
请注意,超级项目不可能记录任何内容除了这个提交哈希。该哈希必须标识子模块的确切状态。如果子模块 Git 存储库确实在该提交上是,并且一切正常,那么上面第二个要点的“预期工作”保证成立。但是,如果子模块 Git 存储库充满了使超级项目工作所需的未提交修改,那么这个“预期工作”的保证就会失效:超级项目说“使用提交 feedc0d...”但 feedc0d...“不是正确的子项目内容。
当你运行git status 时,Git 注意到你在一个有子模块的超级项目中。它在代表子模块的另一个存储库上运行另一个 Git,以获取 its git status。 other Git 报告子模块中有修改。
当你运行git diff 时,Git 会注意到你在这个超级项目中并在子模块上运行另一个git diff,就像git status 一样。该差异表示可能需要先提交一些更改。
直到您真正制作子项目提交,但是,您不能告诉您的(超级项目)Git 记录子模块的新提交。那个新的提交哈希甚至还不存在——它不会存在,并且无法知道或计算,直到你在那里运行git commit,写下提交消息,并让你的姓名和电子邮件地址以及时间commit 全部写入日志。此时,子项目将有一个新提交(在其分离的 HEAD 上),您现在可以在超级项目中记录该新提交的哈希 ID。
在子模块中提交之前...
因为子模块通常处于“分离 HEAD”模式,所以您天真地进行的任何新提交都将不会在分支上。这使得将新提交推送到某个上游存储库中的分支变得更加困难。
请记住,子模块本身就是一个 Git 存储库:要在其中工作,您必须像往常一样在 Git 存储库中工作。这通常意味着你应该在一个分支上——但是因为这个存储库被用作一个子模块,所以超级项目 Git 已经将你 带离了这个分支。因此,在你在那里提交之前,你可能应该回到一个分支上。但是哪个分支?这就是 sub-modules 获得昵称的地方,sob-modules。这里可能有一个好的分支可以使用,但可能没有这里有任何好的分支可以使用。
有关处理此问题的更多信息,请参阅Git commit to common submodule (master branch)。自从糟糕的过去以来,子模块的支持有了显着改善:您现在可以在超级项目中记录一个分支名称,并让超级项目的 Git 告诉子模块的 Git 使用哪个分支。但是,分离的 HEAD 东西仍然是默认设置,并且仍然会妨碍。
没有一种正确的方法可以处理所有这些问题。有很多方法可以奏效,各有优缺点,有些方法根本行不通。不要使用其中一种不起作用。 :-) 一定要在某个分支上提交子模块,即使你必须创建一个分支。
然后,回到超级项目并git add 子项目的新提交哈希。 小心不要意外添加所有子项目的文件,通过路径名补全很容易误操作。那就是:
git add folder1
是正确的,但是:
git add folder1/
不正确。1
现在超级项目已经准备好提交新的(正确的)哈希 ID,您可以使用它进行新的超级项目提交。请注意,您必须先将子模块推送到上游,然后再将超级项目推送到上游,因为任何获得新超级项目提交的人也需要能够从子模块中获取新提交。
1为什么,是的,我已经这样做了。事实上不止一次。