192

我正在寻找有关悬空提交和 blob 的基本信息。

我的存储库似乎很好。但我第一次跑来git fsck看看它做了什么,我有一长串“悬空 blob”和一个“悬空提交”。

这些是什么东西?哪儿来的?它们是否表明我的存储库状态有任何异常(好或坏)?

4

5 回答 5

123

在使用 Git 存储库的过程中,您最终可能会退出操作,并做出其他导致中间 blob 的动作,甚至是 Git 为帮助避免信息丢失而为您做的一些事情。

最终(有条件地,根据git gc 手册页)它将执行垃圾收集并清理这些东西。您也可以通过调用垃圾收集过程来强制它,git gc.

有关这方面的更多信息,请参阅git-scm 站点上的维护和数据恢复。

默认情况下,手动运行 GC 将在此命令运行前两周作为安全网离开。事实上,鼓励偶尔运行 GC 以帮助确保您的 Git 存储库的高性能使用。但是,就像任何事情一样,您应该在销毁那些可能对您很重要的东西之前了解它在做什么。

于 2013-08-29T15:29:58.493 回答
120

Dangling blob = 对暂存区/索引的更改,但从未提交。Git 令人惊奇的一件事是,一旦它被添加到暂存区域,您总是可以取回它,因为这些 blob 的行为就像提交一样,因为它们也有一个哈希!!

悬空提交= 不与任何子提交、分支、标记或其他引用直接链接的提交。你也可以拿回这些!

于 2014-03-06T13:44:20.720 回答
64

如何从http://www.tekkie.ro/news/howto-remove-all-dangling-commits-from-your-git-repository/从你的 Git 存储库中删除所有悬空提交 :

git reflog expire --expire=now --all
git gc --prune=now

确保您确实想要删除它们,因为您可能最终决定需要它们。

于 2016-10-28T11:42:42.967 回答
15

悬空提交是与引用无关的提交,即无法到达它。

例如,考虑下图。假设我们删除分支 featureX 而不合并它的更改,那么提交 D 将成为一个悬空提交,因为没有与之关联的引用。如果它被合并到 master 中,那么 HEAD 和 master 引用将指向提交 D,即使我们删除了 featureX,它也不会再悬空了。阅读图表后的注释以更好地理解这一点。

Git 自动垃圾收集(即处置)悬空提交。我们可以使用git reflog来恢复一个分支(悬空提交),该分支在没有合并的情况下被删除。只有当它存在于本地对象存储中时,我们才能恢复已删除的提交。如果它被垃圾收集,那么我们就无法恢复它。

在此处输入图像描述

请注意,分支名称,即分支标签,实际上是对分支上最新提交的引用,即分支的尖端。在上图中,featureX、master 和 HEAD 只是对特定提交的引用。featureX 和 master 标签指的是各自分支上的最新提交。HEAD 一般是指当前签出的分支(本例中为 master)的尖端。如果您在当前分支上签出较旧的提交,则 HEAD 将处于分离状态,即,它将指向较旧的提交而不是最新的提交。另请注意,HEAD 被称为符号引用,因为它实际上指向当前分支标签,并且任何分支标签始终指向分支的尖端。所以,一般情况下,HEAD 间接指向了最新的提交。

顺便说一句,请注意 Git 将其提交图/历史表示为有向无环图。每个提交都有对其父级的引用。因此,提交图中的箭头指向从子提交到父提交。我们需要引用最新的子提交,以便访问分支上较旧的提交。

PS-上面的图表和理解是从这个免费课程中获得的。尽管课程已经很老了,但知识仍然是相关的。

于 2020-01-21T23:43:38.090 回答
2

如果您“修改”提交,也会出现悬空提交。例如,您做了很多工作,对其进行测试并提交所有文件,然后记住您忘记更新 README 文件。所以你快速改变它,添加它,然后使用“git commit --amend”。这将创建一个链接到提交历史的新提交,并且原始提交处于悬空状态。

于 2021-08-10T15:18:42.587 回答