【问题标题】:GIT - Remove old reflog entriesGIT - 删除旧的 reflog 条目
【发布时间】:2018-08-10 14:18:08
【问题描述】:

根据我们的最新需求对存储库进行了大量的 rebase 之后,我们的 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> ...

正如您在主分支下方看到的,旧的提交/分支在 rebase 之前说明了存储库。

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

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

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

我怎样才能做到这一点?


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

请不要提及删除并重新克隆存储库。这不是我要找的。​​p>


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

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

git reflog expire --expire=all

什么都没有发生,所以我试图变得聪明并调用了垃圾收集器

git gc --aggressive

但是假的。

【问题讨论】:

标签: git purge git-reflog


【解决方案1】:

具体来说,您需要--expire-unreachable 选项:

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

例如。

有什么区别?

reflog 是一个参考日志(因此得名“reflog”:-))。 referenceref 是以refs/ 开头的名称,例如refs/heads/master,这就是分支名称master 的实际存储方式。对于HEAD 本身,有一个额外的参考日志,它(因为它不是以refs/ 开头)在技术上不是我在the gitglossary 中链接的定义的参考,但是随后,词汇表定义继续说有一些特殊的引用不是以refs/ 开头的,所以要么他们感到困惑,要么我很困惑。 :-)

无论如何,引用的意义在于存储哈希 ID(或者在特殊的 HEAD 引用的情况下,存储另一个引用的名称)。哈希 ID 是一个值。您可以更新引用,这会更改存储的值——因此,随着时间的推移,单个名称会采用多个不同的值。有 当前master,然后是从一更改前的一个,master@{1},从两个更改前,master@{2},等等。 (为保持一致,您可以根据需要拼写当前值master@{0}。)这一切都在the gitrevisions documentation 中进行了拼写。

reflog 是 Git 保存 previous 值的地方。 reflog 不仅存储先前的值,还存储值更改时计算机的时钟时间——因此 Git 可以处理 master@{3.days.ago} 之类的语法来查找任何条目,master@{0}master@{1}master@{2} 或其他任何条目,表示三天前的值master。 (“三天”是指 3 个 24 小时日:72 小时,没有分,也没有秒前,或者正好是 259200 秒前。如果你昨天更改了几次 master,你可能需要比 master@{yesterday} 更精确.)

无论如何,所以,假设master当前 值是1234567...(一些大而丑陋的哈希ID),并且master@{1}8888888...master@{2} 是@ 987654349@。到目前为止,它们看起来都很相似。但不一定如此:

          1234567   <-- master
            /
...--o--8888888   [master@{1}]
      \
    3333333   [master@{2}]

master@{1}master@{2} 之间的区别在这里——嗯,除了它们的值和花括号 {} 内的数字——与git reflog expire重要区别在于我们可以 find master@{1}master (1234567) 开始并向后工作。如果我们从master 开始并返回一个提交,我们就会来到master@{1}。如果我们再往前走一步,我们会到达无聊的提交o,我们甚至不知道它的编号;我们直接跳过提交3333333

具体来说,在这种情况下,master@{2} 与当前的 (1234567) 值 master 相比无法访问。所以它的到期时间由--expire-unreachable 参数控制,而不是由--expire 参数控制。

如果您不选择特定值,git reflog 将使用配置的默认值(如果您已配置)。在没有配置默认值的情况下,default 默认值是 90 天(可访问条目)和 30 天(不可访问条目)。所以:

--expire=90.days.ago --expire-unreachable=30.days.ago

是默认值,除非您更改了自己的默认值。如果您在命令行上覆盖 one 默认值,您将保留 other 默认值。

Rebase 导致很多不可访问

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

          A'-B'-C'  <-- branch
         /
...--o--o
         \
          A--B--C   [branch@{1}]

A--B--C 是原始链(旧的和 icky 提交),A'-B'-C' 是您想要的闪亮的新副本。由于连接总是向后走,旧的连接总是无法从新的分支提示中访问,即使它们可以从其他一些引用中访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-16
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多