列出并删除没有所属分支的Git提交记录(悬挂?)

12 浏览
0 Comments

列出并删除没有所属分支的Git提交记录(悬挂?)

我有一个Git存储库,其中有许多没有特定分支的提交,我可以使用git show查看它们,但是当我尝试列出包含它们的分支时,它报告没有任何内容。

我认为这是挂起的提交/树问题(由于-D分支的结果),因此我修剪了存储库,但是在那之后我仍然看到相同的行为:

$ git fetch origin
$ git fsck --unreachable
$ git fsck

没有任何输出,也没有任何挂起(对吗?)。但是提交存在

$ git show 793db7f272ba4bbdd1e32f14410a52a412667042
commit 793db7f272ba4bbdd1e32f14410a52a412667042
Author: ...

它不能通过任何分支到达,因为

$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

没有输出。

那个提交的状态是什么?我如何列出所有处于类似状态的提交?我如何删除这些提交?

admin 更改状态以发布 2023年5月24日
0
0 Comments

没有输出,没有悬挂的东西(对吧?)

请注意,从您的reflog引用的提交被认为是可访问的。

那个提交的状态是什么?我如何列出所有具有类似状态的提交

传递--no-reflogs以确信git fsck向您显示它们。

我如何删除这些提交?

一旦您的reflog条目过期,这些对象也将被git gc清除。

过期由gc.pruneexpiregc.reflogexpiregc.reflogexpireunreachable设置调节。参见git help config

默认值都相当合理。

0
0 Comments

要删除所有挂起的提交(包括从存储库和其他reflog中仍然可达到的提交),请执行以下操作:

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

但请确定这就是你想要的。我建议你阅读手册,但是这是要点:

git gc会删除不可达对象(提交、树、blob(文件))。如果一个对象不是某个分支历史的一部分,则它是不可达的。实际上,情况要复杂一些:

存储库使用reflog实现了挂起(而不是分支或标签)。这意味着它们也会被垃圾回收。

git gc还做了其他一些事情,但这里不相关,也不危险。

两周以内的不可达对象不会被删除,因此我们使用--prune=now,表示“删除在现在之前创建的不可达对象”。

对象也可以通过reflog到达。虽然分支记录了项目的历史,但reflog记录了这些分支的历史。如果进行修订、重置等操作,则提交会从分支历史中删除,但git会保留它们,以防你意识到自己犯了错误。reflog是一个方便的方式,可以了解在分支(或HEAD)上执行了哪些破坏性(或其他)操作,从而更容易地撤消破坏性操作。

因此,我们还必须删除reflog才能真正删除所有不可达分支。我们通过过期所有reflog来实现这一点:--all。再次地,git会保留reflog的一部分以保护用户,因此我们还要告诉它不要这样做:--expire-unreachable=now

由于我主要使用reflog从破坏性操作中恢复,所以我通常使用--expire=now,这样可以完全清除reflog。

0