Git:悬空的Blob

66

我最近在我的代码库上运行了git fsck --lost-found命令。

我预期会看到一些悬空提交,因为我曾经重置过HEAD

然而,让我惊讶的是,我看到了几千个可能是悬空blob消息。

我不认为我的代码库有什么问题,但我很好奇是什么导致了这些悬空的blob?我们只有两个人在代码库上工作,并没有做任何特殊的事情。

我认为这些悬空的blob不是由于旧版本的文件被新文件替换造成的,因为git需要同时保留这两个blob以便显示历史记录。

现在想起来,我们曾经把一个非常大的目录(数千个文件)误添加到项目中,然后将其删除。这会是所有悬空blob的来源吗?

我只是想了解这个谜团的原因。

3个回答

58

我上次看到这个问题时,偶然发现了这个讨论串,特别是其中的这一部分:

你也可能会在打包中遇到悬挂对象。当打包被重新打包时,那些对象将会被释放,然后最终根据上述规则过期。然而,我相信gc并不总是重复旧的打包;它会制作新的打包,直到你有很多打包,然后再把它们合并起来(至少“gc --auto”会这样做,我不记得只有“git gc”是否遵循同样的规则)。

因此,这是正常行为,并且最终会被垃圾回收,我相信如此。

编辑:根据Daniel的说法,您可以通过运行以下命令立即进行回收:

git gc --prune="0 days"

3
如果移除那些 blob,会发生什么? - NFerocious
@nferocious76 如果您无法挽救那些被添加到暂存区但未提交并随后被删除(通过rm -f)的文件,则一旦GC运行,这些文件将永久丢失。 - David Brower
@DavidBrower 我明白了,谢谢。所以它也会删除未链接或未引用的文件。 - NFerocious
1
git gc --prune=all - andrej

28

我非常不耐烦,使用了以下代码:

git gc --prune="0 days"

16
无论何时您将文件添加到索引中,该文件的内容都会作为blob添加到Git的对象数据库中。当您重置/移除该文件时,blob仍然存在(它们将在下次运行gc时被垃圾回收)。
但是,当这些文件是提交的一部分并且您稍后决定重置历史记录时,旧的提交仍然可以从Git的reflog中访问,并且只能在一段时间后(通常为一个月)进行垃圾回收。这些对象不应显示为悬空状态,因为它们仍然从reflog引用。

2
值得注意的是,如果您修复了一个文件并重新add它,那么以前的文件将以同样的方式成为悬空的blob。(通常我使用以下顺序:修改代码,git addgit diff --cached和/或git status直到满意,然后git commit,所以我会有很多这样的情况。 :-) ) - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接