我有一个指向无效提交的子模块的项目:子模块提交仍然是本地的,当我试图从另一个repo获取它时,我得到:

$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout '2d7cfbd09fc96c04c4c41148d44ed7778add6b43' in submodule path 'mysubmodule'

我知道子模块HEAD应该是什么,有没有办法我可以在本地改变这个,而不从已经提交2d7cfbd09fc96c04c4c41148d44ed7778add6b43的回购?

我不确定我是否说清楚了…我发现了一个类似的情况。


当前回答

当我这样做时,我得到了这个错误:

$ git submodule update --init --depth 1

但是父项目中的提交指向了之前的提交。

删除子模块文件夹并运行:

$ git submodule update --init

并没有解决问题。我删除了回购,并再次尝试没有深度标志,它工作了。

此错误发生在Ubuntu 16.04 git 2.7.4中,但不会发生在Ubuntu 18.04 git 2.17中。

@pavan kumar在评论中写道:

我只是增加了深度计数以包括旧的提交,它起作用了。

其他回答

你的分支可能不是最新的,一个简单的解决方案,但尝试git获取

当我这样做时,我得到了这个错误:

$ git submodule update --init --depth 1

但是父项目中的提交指向了之前的提交。

删除子模块文件夹并运行:

$ git submodule update --init

并没有解决问题。我删除了回购,并再次尝试没有深度标志,它工作了。

此错误发生在Ubuntu 16.04 git 2.7.4中,但不会发生在Ubuntu 18.04 git 2.17中。

@pavan kumar在评论中写道:

我只是增加了深度计数以包括旧的提交,它起作用了。

可能的原因

这可能发生在以下情况:

子模块已编辑到位 提交子模块,更新所指向的子模块的散列 没有推送子模块。

例如:发生了这样的事情:

$ cd submodule
$ emacs my_source_file  # edit some file(s)
$ git commit -am "Making some changes but will forget to push!"

此时应该已经推送了子模块。

$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git push origin master

因此,远程用户不可能找到丢失的提交,因为它们仍然在本地磁盘上。

解决方案

通知修改子模块以推送的人,即。

$ cd submodule
$ git push

当你有一个子模块指向一个重新基于的存储库,并且给定的提交“消失”时,也可能发生这种情况。虽然提交可能仍然在远程存储库中,但它不在分支中。如果你不能创建一个新的分支(例如,不是你的存储库),你就不得不更新超级项目来指向一个新的提交。或者,您可以将子模块的一个副本推到其他地方,然后更新超级项目以指向该存储库。

在我看来,上面的答案都不能解决问题,尽管它们是很好的答案。所以我发布了我的解决方案(在我的例子中有两个git客户端,客户端A和B):

进入子模块的目录: cd子 结帐要掌握: Git checkout master 重基为两个客户端都能看到的提交代码 回到父目录: 致力于掌握 更改到另一个客户端,再次做rebase。 现在终于可以正常工作了!可能会丢失一些提交,但它是有效的。 仅供参考,不要试图删除你的子模块,它将保留在那里。git/modules,并且不能再次读取该子模块,除非响应式本地。