GIT - 删除旧的reflog条目

时间:2018-03-02 11:07:56

标签: git purge git-reflog

经过大量重新定位存储库以满足我们的最新需求后,我们的reflog充满了提交和孤立分支。我们达到了重组的最终状态。

虽然存在大量二进制数据的分支和提交,但存储库增长了其原始大小的多倍,我们决定清除所有旧的reflog条目和数据。

我正在挖掘手册,但没有更聪明地尝试git-reflog expire

这是日志(缩短)

的示例
-> <sha1> [development] ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
-> <sha1> [master] ...
-> <sha1-old> ...
| <sha1-old> ...
| <sha1-old> ...
| <sha1-old> ...
| <sha1-old> ...
| <sha1-old> ...
| <sha1-old> ...
| <sha1-old> ...
-> <sha1-old> ...

正如您在主分支下面看到的那样,旧的提交/分支在变基之前说明了存储库。

我们希望清除reflog以使存储库看起来像

-> <sha1> [development] ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
| <sha1> ...
-> <sha1> [master] ...

我们希望减少存储库使用的磁盘空间。

我怎样才能实现这一目标?

编辑(2019-03-02 12:20)

请不要提及删除并重新克隆存储库。这不是我正在寻找的。

编辑(2019-03-02 12:30)

到目前为止我尝试了什么,但没有效果

git reflog expire --expire=all

没有任何事情发生,所以我试图聪明并调用垃圾收集器

git gc --aggressive

但是虚假。

1 个答案:

答案 0 :(得分:5)

具体而言,您需要--expire-unreachable选项:

git reflog expire --expire=90.days.ago --expire-unreachable=now --all
例如

有什么区别?

reflog 是一个参考日志(因此名称为&#34; reflog&#34; :-))。 引用ref是以refs/开头的名称,例如refs/heads/master,这是分支名称master的真实存储方式。 HEAD本身有一个额外的reflog,它(因为它不以refs/开头)在技术上不是我在the gitglossary中链接的定义的引用,但是,术语表定义继续说有些特殊的参考文献不是以refs/开头的,所以要么他们感到困惑,要么就是我。 : - )

无论如何,引用的要点是存储一个哈希ID(或者在特殊HEAD引用的情况下,存储另一个引用的名称)。哈希ID是一个值。您可以更新引用,该引用会更改存储的值 - 因此,随着时间的推移,单个名称将采用多个不同的值。 当前master,然后是一个变更前的master@{1},以及之前的两个变更master@{2},等等。 (为了保持一致性,如果您愿意,可以拼写当前值master@{0}。)这些都在the gitrevisions documentation中拼写出来。

reflog 是Git保留之前值的地方。 reflog不仅存储了以前的值,还存储了值更改时计算机的时钟时间 - 因此Git可以处理master@{3.days.ago}之类的语法来查找任何条目master@{0}或{{ 1}}或master@{1}或其他,表示三天前的值master@{2}。 (&#34;三天&#34;意味着3个24小时工作日:72个小时,没有分钟,没有几秒钟,或者正好是259200秒之前。如果您昨天多次更改master,则可能需要比master更精确。)

无论如何,假设master@{yesterday}当前值为master(一些丑陋的哈希ID),1234567...为{{1} } master@{1}8888888...。到目前为止,它们看起来都很相似。但他们并非如此:

master@{2}

3333333... 1234567 <-- master / ...--o--8888888 [master@{1}] \ 3333333 [master@{2}] 之间的差异 - 除了它们的值和花括号master@{1}内的数字 - 重要与{{ 1}}我们可以通过从master@{2}{})开始并向后工作来查找 git reflog expire。如果我们从master@{1}开始并返回一个提交,我们来master。如果我们回到另一个步骤,我们会得到无聊的提交1234567,我们甚至不知道这些提交的号码;我们跳过提交master

具体而言,在这种情况下,master@{1} 无法访问来自o的当前(3333333)值。因此它的到期时间由master@{2}参数控制,而不是由1234567参数控制。

如果您没有选择特定值,master将使用配置的默认值(如果您已配置一个)。如果没有配置的默认值,默认默认值为可达条目的90天和无法访问的条目的30天。所以:

--expire-unreachable

是默认设置,除非您更改了自己的默认设置。如果在命令行上覆盖一个默认值,则单独保留其他默认值。

Rebase制作了大量不可访问的内容

你的问题从重要的一点开始:你做了很多改变。 Rebase通过复制提交工作,然后切换分支名称以使用新的(并且可能是改进的)提交。旧的仍然存在,并且总是无法通过新的分支提示:

--expire

其中git reflog是原始链(旧的和icky提交),--expire=90.days.ago --expire-unreachable=30.days.ago 是您想要的闪亮新副本。由于连接总是向后移动,所以旧的分支提示总是无法从新的分支提示中访问,即使它们可以从其他一些引用中找到。