为了好玩,我试图将大约85GB的大小主要在6MB左右的二进制文件放入Git中。Git开始运行一段时间,但总是在一半左右失败,并显示消息“fatal: confused by unstable object source data”,后面跟着一个SHA1。您知道原因吗?有什么方法可以修复它吗?
要么:
简短版:Git 的开发人员没有打算将其用于易变文件。
由于 Git 用于“松散对象”的布局*和它所假定的有限文件系统语义**,Git 必须在开始存储新对象之前知道新对象名称(SHA-1)的第一个字节(两个十六进制字符)。
*
objects/[0-9a-f][0-9a-f]/
目录。请参见 gitrepository-layout
。
**
具体来说,它需要能够执行“原子”文件重命名。某些文件系统(通常是网络文件系统;我认为特别是 AFS)仅在重命名的源和目标位于同一目录内时才保证重命名的原子性。
当前,Git 对每个新文件进行两次 SHA-1 操作。第一次操作用于检查 Git 是否已经知道文件的内容(即其 SHA-1 对象名称是否已存在于对象存储中)。如果对象已经存在,则不进行第二次操作。
对于新的内容(对象尚未存在于对象存储中),在压缩和计算正在压缩的数据的 SHA-1 时,文件会再次被读取。压缩后的数据将被写入临时文件,只有当最初的 SHA-1(“已存储?”检查)与稍后的 SHA-1(已压缩并写入的数据的哈希值)匹配时,该文件才会被重命名为其最终松散对象名称。如果这些 SHA-1 哈希值不匹配,则 Git 显示您所看到的错误消息并中止。此错误检查是在 748af44c63 中添加的,该版本首次发布于 Git 1.7.0.2。还有一种可能性,即使很小概率。那就是一个非常大的文件(例如3个或更多GB),简单来说,git无法处理它。 我们在尝试在一个包含巨大文件的结构中创建存储库时发现了这个错误。
两种可能:
有些东西正在你试图将它们放到git中的文件中写入。
你可能有某种磁盘/内存故障导致数据损坏。
虽然其他回答已经非常好地解释了为什么会出现这个错误,但是这里提供一种可能的解决方案:
找到有问题的文件,将 -v 添加到你的 git add 命令中,这将给你一些关于有问题的文件的线索:
git add -Av
如果您尝试在btrfs文件系统上使用git svn clone或git svn fetch克隆/获取存储库,可能会发生此情况,这可能与btrfs cow功能内部的竞争条件或原子性有关。
例如:
git svn --authors-file=authors.map clone http://svn.example.com/svn/repo repo
或者
cd repo; git svn --authors-file=../authors.map fetch
我发现了一个解决方法,通过设置您的基本工作目录而不进行写时复制:
chattr +C .
然后你需要复制所有的数据(例如):
cp -fr repo repo.new; rm -fr repo; mv -f repo.new repo
cp authors.map authors.map.new; mv -f authors.map.new authors.map
那么它就不应该失败(并且运行得更快)。