列出并删除没有所属分支的Git提交记录(悬挂?)
列出并删除没有所属分支的Git提交记录(悬挂?)
我有一个Git存储库,其中有许多没有特定分支的提交,我可以使用git show
查看它们,但是当我尝试列出包含它们的分支时,它报告没有任何内容。
我认为这是挂起的提交/树问题(由于-D分支的结果),因此我修剪了存储库,但是在那之后我仍然看到相同的行为:
$ git fetch origin $ git fsck --unreachable $ git fsck
没有任何输出,也没有任何挂起(对吗?)。但是提交存在
$ git show 793db7f272ba4bbdd1e32f14410a52a412667042 commit 793db7f272ba4bbdd1e32f14410a52a412667042 Author: ...
它不能通过任何分支到达,因为
$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042
没有输出。
那个提交的状态是什么?我如何列出所有处于类似状态的提交?我如何删除这些提交?
没有输出,没有悬挂的东西(对吧?)
请注意,从您的reflog引用的提交被认为是可访问的。
那个提交的状态是什么?我如何列出所有具有类似状态的提交
传递--no-reflogs
以确信git fsck
向您显示它们。
我如何删除这些提交?
一旦您的reflog条目过期,这些对象也将被git gc
清除。
过期由gc.pruneexpire
、gc.reflogexpire
和gc.reflogexpireunreachable
设置调节。参见git help config
。
默认值都相当合理。
要删除所有挂起的提交(包括从存储库和其他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。