Git:什么是悬空提交/ blob,它们来自哪里?

dou*_*ack 128 git git-commit git-fsck git-dangling

我正在寻找关于悬挂提交和blob的基本信息.

我的回购似乎很好.但是我git fsck第一次跑去看看它做了什么,我有一长串的'悬空blob'和一个'悬挂提交'.

这些是什么东西?哪儿来的?他们是否表明我的回购状态有什么异常(好的或坏的)?

Eli*_*ynn 84

悬空blob =一个变化,它使它进入临时区域/索引但从未被提交.使用git令人惊讶的一件事是,一旦它被添加到临时区域,你总是可以将它恢复,因为这些blob的行为类似于提交,因为它们也有哈希!

Dangling commit =未通过任何子提交,分支,标记或其他引用直接链接的提交.你也可以回来了!

  • '祖先'应该读'后代'吗?通常,您无法通过其祖先进行任何git提交. (5认同)

vgo*_*off 80

在使用您的git存储库的过程中,您可能最终退出操作,并进行导致中间blob的其他操作,甚至git为您做的一些事情,以帮助避免信息丢失.

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

有关此内容的更多信息,请参阅git-scm站点上的维护和数据恢复.

默认情况下,手动运行GC将在安全网的此命令运行之前2周离开.实际上鼓励偶尔运行GC以帮助确保高效使用您的git存储库.但是,就像任何东西一样,你应该在破坏那些可能对你很重要的东西之前理解它在做什么.

  • 因此可以公平地说1)除非我认为我的回购有一些问题,用`git gc`删除它们是安全的,2)我根本不需要担心这个,因为这些悬空位是正常和git已经处理了吗? (7认同)
  • 此外,任何时候你'git'添加'文件,但不提交文件的确切版本,你最终会有一个悬空blob.没什么好担心的. (7认同)
  • doub1ejack - 一般来说,你不应该手动运行垃圾收集.进入并且git在需要时进行垃圾收集是一个坏习惯.手动运行它的缺点是你失去了恢复悬挂blob和你现在可能不想要的提交的能力,但你将来可能会想要.一旦你运行垃圾收集,你就会从git中删除一些非常强大的恢复功能.谨慎使用,作为例外,而不是规则.---让git做它的事. (7认同)
  • 这将是一个公平的评估. (6认同)

qxo*_*qxo 35

HOWTO从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
Run Code Online (Sandbox Code Playgroud)

确保你真的想删除它们,因为你可能认为你毕竟需要它们.

  • 实际上,大多数用户永远不需要这样做,如果他们这样做,可能是一个程序化的用例.通过删除悬空提交节省的磁盘空间或速度增加在我看来是不值得的. (4认同)
  • 这回答了一个不同的问题。 (4认同)

Mas*_*oe2 11

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

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

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

在此处输入图片说明

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

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

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


小智 10

如果您“修改”提交,也会出现悬空提交。例如,您做了很多工作,测试它并提交所有文件,然后记得您忘记更新 README 文件。因此,您可以快速更改它,添加它,然后使用“git commit --amend”。这将创建一个链接到提交历史记录的新提交,而原始提交则悬空。