我有分支“ dev”。最后一个分支开发人员有一个空文件夹libtai-mutoso。我在Windows上使用Gitbash。 我已经完成了另一个分支的工作,并且打算将git切换到分支“ dev”。但是git不结帐:
$ git checkout dev -f
error: invalid object 160000 0000000000000000000000000000000000000000 for 'Src/time/libtai-mutoso'
error: invalid object 160000 0000000000000000000000000000000000000000 for 'Src/time/libtai-mutoso'
error: cache entry has null sha1: Src/time/libtai-mutoso
fatal: unable to write new index file
我现在如何切换到dev分支? 大师,谢谢您的帮助!
答案 0 :(得分:1)
最后一个分支dev的空文件夹libtai-mutoso。
Git实际上不能存储一个空文件夹,而您却没有这样做。发生的事情是有人试图欺骗您的Git来存储一个空文件夹...而该欺骗失败了。
有两个相关的技巧,How can I add an empty directory to a Git repository?中都有描述,其中之一是使用特殊的 empty tree 哈希,如this answer中所述。正如答案本身指出的那样,它实际上并不正确。另一种方法是使用this answer中所述的空子模块。此方法有效(有一些限制)。
似乎是谁构建了您克隆的存储库并试图立即使用它,试图使用子模块技巧的人,但都弄错了。
子模块技巧利用了以下事实:当Git在有关 gitlink 的信息中存储有关子模块的信息时,该信息就是您在错误消息中看到的带有mode 160000
的实体,超级项目Git将创建一个目录/文件夹,然后(当您告诉它时)在该目录中创建一个.git
并克隆子模块,并使用子模块克隆为该目录填充内容。>
请注意,最后这个新目录/文件夹并不为空:它包含一个.git
,然后您的超级项目Git也会在某个时候运行git checkout
,以在子模块中用一些提交的内容填充文件夹。但是所有这些都会在以后告诉您的Git进行。如果您从不告诉Git 填写我的子模块,那么它甚至都不会进入创建.git
。 1
您的Git所需的信息,包括您的超级项目Git应该克隆的Git存储库以及之后应检出的提交,都包含在超级项目的两个位置:
.gitmodules
中,并且git checkout
的提交哈希ID是您在上面的错误消息中看到的哈希ID。哈希ID 必须是该子模块存储库中实际存在的某些提交的有效哈希ID。超级项目Git通常实际上不会检查是否有效-仍然不是:该检查稍后发生。但是有一种特例,您刚刚看过。
具体来说,Git中的哈希ID 0000000000000000000000000000000000000000
(40个零)是保留的,在某些地方称为 null hash ID 或 null sha1 ,包括您看到的错误消息:
error: cache entry has null sha1
在某些特殊情况下,高速缓存条目只能具有此空哈希ID,而这不是这些特殊情况之一。
在您的Git执行超级项目提交的git checkout
时,需要存在正确的信息,以使您的Git不会抱怨有什么问题并拒绝检出提交。但是在您克隆的存储库中,您尝试检出的提交中的信息是错误的。
因此,总结一下问题:有人尝试使用子模块技巧,但是弄错了。结果是您的 Git拒绝签出的提交。
我现在如何切换到dev分支?
让任何使存储库出错的人停止使用子模块。
您(和他们)最好的选择是根本不去尝试存储一个空文件夹。这不值得麻烦。如果他们打算存储一个真实的子模块(可能的话),请他们修复存储库,使其具有正确的子模块。
1 如果并且当您 do 告诉超级项目Git更新子模块时,如果您使用了有效的“空子模块”技巧,则克隆的存储库将具有提交中没有文件。该答案中的示例使用提交e84d7b81f0033399e325b8037ed2b801a5c994e0
。因此,该目录最后带有一个名为.git
的条目。在现代Git中,此.git
是一个包含一行的文件。在较早的Git版本中,它是一个目录,其中包含empty-submodule存储库的克隆,其中包含一个没有文件的提交。