Git:从远程获取特定对象

Yve*_*rès 7 git

在工作中,我们必须应对一个非常庞大的git存储库(90Go).尝试在我的本地副本上调整一些东西(我有一个包文件的错误,试图解压缩它),我可能已经删除了一些目标文件.例如:

> git gc

错误:无法读取af9ed8 [:snip:]

致命的:坏树对象af9ed8 [:snip:]

错误:无法运行重新包装

如何从远程存储库中获取特定对象(在这种情况下是具有散列af9ed8的那个...)?

Cas*_*bel 5

如果您可以访问包含此对象的远程或任何其他完整存储库的文件系统,您应该能够去那里运行:

git cat-file tree af9ed8 > 9ed8...
Run Code Online (Sandbox Code Playgroud)

请注意,这仅需要对 repo 的只读访问权限(您可以在其他地方写入文件),因此它应该非常安全,您甚至可以以没有文件系统写入权限的用户身份执行此操作。然后,您可以将其传输/复制到您的存储库中的适当位置:

cp path/to/9ed8... .git/objects/af/9ed8...
Run Code Online (Sandbox Code Playgroud)

松散对象存储在具有哈希前两位数字的目录中;文件名是散列的其余部分。

编辑:如果对象在远程端松散,您也可以直接将其复制出.git/objects,但如果它已打包,则必须使用 解压缩它git unpack-objects,我想该存储库中的打包文件大得令人望而却步。最好的方法是将打包文件复制到损坏的存储库中,删除任何损坏的对象,然后使用git unpack-objects < packfile,这不会解压缩任何已经存在的对象。

我不确定如何通过普通的远程命令来做到这一点;即使较低级别git fetch-pack仍然在 ref 级别运行,获取具有必要提交的包以完成 ref。我怀疑您可能会做一些偷偷摸摸的事情,例如删除引用该树的所有提交对象(git fsck可能会帮助您找到它们)。我真的希望你能够创建一个指向该对象的标签,将它推送到远程,然后尝试从远程获取标签(诱使它获取对象),但看起来 Git 非常小心,不要让您创建或操作指向不存在对象的标记。