git fsck:如何--dangling与--unreachable vs. --lost-found有何不同?

aka*_*vel 3 git

我最近发现了git fsck,但链接的答案并git help fsck列出了各种替代选项,其中一些似乎与未经训练的眼睛相同.为了能够很好地使用该工具,我想了解以下命令之间的区别是什么?

  • git fsck --dangling
  • git fsck --unreachable
  • git fsck --lost-found

此外,可以/应该在某些组合中一起使用,还是更好?

(作为旁注,我特别感兴趣的是使用它git log -G$REGEX $(git fsck --something),尽可能地扩大网络,我希望找到一些我记得在某些时候写过的东西,但是我找不到它git log -G$REGEX -a.)

tor*_*rek 8

部分答案在git词汇表中,我们在其中找到:

悬空物体

一个无法访问的对象,即使从其他无法访问的对象也无法访问 ; 悬空对象没有从存储库中的任何引用或对象引用它.

(所有链接他们的).可达性(如果你愿意,可以按照它们的链接)是git提交图中的一个基本概念,我们从一些外部引用开始,如分支或标记名称,以获取图中的起点,然后按照每个节点的出站边找到所有其他节点.

(有一个ref的词汇表条目,但不供参考,但参考只是在这里有它的常规字典.)

不过,我认为这是最好的说明.假设我们有一个如下所示的提交DAG:

     C--D--E      <-- branch-a
    /
A--B--F---G--H    <-- branch-b
    \    /
     I--J--K--L   <-- branch-c
Run Code Online (Sandbox Code Playgroud)

节点始终指向left-ish,同时可能也指向上或下,因此节点E例如指向返回D,指向C哪个点处的BA.(A点无处:它是一个节点.)节点G是合并并在两个点背FJ.在该图中的每个节点可到达:从我们所有的外部引用(分公司)开始,然后步行离开十岁上下,并发现节点A通过Ebranch-a; 节点A,BF通过Gbranch-b; 等等.(注意节点A并且B每个分支上.节点可以在许多分支上的事实是关于git有点不寻常的事情.例如,在mercurial中,每个节点只在一个分支上.特别的方式,git的分支是流动的,而mercurial是固定的.)

现在让我们看看如果我们删除其中一个分支标签会发生什么.让我们branch-a先剥掉标签.

提交E不再有任何指向它的东西.这是不可达,而且,在Git的任期这里- 晃来晃去.Commit D只提交E指向它.由于E无法访问,D也无法访问,但D晃来晃去,因为ED. C与...处于同一状态D.节点B,而另一方面,是从可到达的branch-b通过以下HGFB,并且由以下HGJIB,branch-c由以下LKJIB.

让我们把branch-a标签放回去(以便C通过E再次到达)然后剥离branch-c.这一次LK不可达.J但是,节点仍然可以通过开始branch-b和工作HG访问J.的KL提交,仅L是晃来晃去,因为LK.

git fsck正如我在其他答案中所提到的,当使用时,--lost-found通过将其ID或内容写入来"复活"(某些)悬空物体.git/lost-found/.

(请记住,提交指向以前的提交,而blob只是文本,并且从不指向任何内容.当您删除分支时,或者当重新设置并因此放弃的提交链丢失其reflog引用时,您将获得悬空提交,例如,所以它们很正常.当你git add文件的内容时,你会得到悬空的blob ,然后是git reset它或者git add没有先提交的新内容,所以摇晃的blob非常正常. git fsck不保存悬空树或标记对象.通常应该没有悬空的树:树对象只能指向更多的树和blob,并且任何悬空树通常都应该由提交指向;并且你必须git write-tree手动使用,然后不要引用树,以获得悬空树.我是不确定为什么标签对象没有复活,因为不小心删除了带注释标签的外部引用导致悬挂标签对象,并且能够让它们恢复原状可能会很好.)

摘要:git fsck检测和恢复悬空或未引用的对象

无法访问的对象是那些无法从外部引用访问的对象(主要是分支和标记名称,尽管还有其他类似的refs/stash,使用过的git stash).悬空对象是无法到达的对象的子集,特别是那些没有入站弧的对象(以图形理论术语表示).

添加--lost-found标志将保存悬空提交的ID - 这使得这些提交,因此任何其他未引用的提交,所有再次引用 - 并解压缩并使所有悬空blob对象可用.