在工作中,我们必须应对一个非常庞大的git存储库(90Go)。 尝试在我的本地副本上调整一些东西(我有一个包文件的错误,试图解压缩它),我可能已经删除了一些目标文件。 例如:
> git gc
错误:无法读取af9ed8 [:snip:]
致命:坏树对象af9ed8 [:snip:]
错误:无法运行重新包装
如何从远程存储库中获取特定对象(在这种情况下是具有散列af9ed8的那个...)?
答案 0 :(得分:4)
如果您具有远程的文件系统访问权限或包含此对象的任何其他完整存储库,您应该可以去那里运行:
git cat-file tree af9ed8 > 9ed8...
请注意,这只需要对repo进行只读访问(您可以将文件写入其他位置),因此它应该非常安全,您甚至可以将其作为对文件系统没有写入权限的用户进行操作。然后,您可以将其传输/复制到您的仓库中的适当位置:
cp path/to/9ed8... .git/objects/af/9ed8...
松散的对象存储在具有散列的前两位数的目录中;文件名是哈希的其余部分。
编辑:如果对象在远程端松动,您也可以直接将其从.git/objects
复制出来,但是如果它已打包,则必须用git unpack-objects
解压缩它,然后我想象那个回购中的包装文件非常大。最好的方法是将packfile复制到损坏的repo中,删除任何损坏的对象,然后使用git unpack-objects < packfile
,它不会解压缩任何已存在的对象。
我不确定如何通过普通的远程命令来做到这一点;即使是较低级别的git fetch-pack
仍然在ref级别运行,获取包含必要提交的包以完成引用。我怀疑你可能会做一些偷偷摸摸的事情,比如删除所有引用该树的提交对象(git fsck
可能会帮助你找到它们)。我真的希望你能够创建一个指向该对象的标签,将其推送到遥控器,然后尝试从遥控器获取标签(将其哄骗到获取对象)但看起来Git非常小心不要让您制作或操作指向不存在的对象的标记。