GIT-删除旧的reflog条目 [英] GIT - Remove old reflog entries

查看:257
本文介绍了GIT-删除旧的reflog条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将存储库重新部署到最新需求之后,我们的reflog充满了提交和孤立分支.我们达到了重组的最终状态.

After a lot of rebasing a repository to our latest needs our reflog is full of commits and orphan branches. We reached the final state of our reorganization.

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

While there're branches and commits left with a lot of binary data the repository grew multiple times of its origin size we decided to purge all the old reflog entries and data.

我正在研究手册,但对

I was digging in the manual but didn't get much smarter experimenting with git-reflog expire

这是一个日志示例(已缩短)

This is an example of the log (shortened)

-> <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> ...

如您所见,在master分支下方,有旧的commits/分支说明了在变基之前的存储库.

As you can see below the master branch there is the old commits / branches stating the repository before the rebase.

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

We expect to clear the reflog to have the repository look like

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

为了期望减少存储库使用的磁盘空间.

In order we expect to reduce the disk space used by the repository.

我该怎么做?

请不要提及删除并重新克隆存储库.这不是我想要的.

Please do not mention to delete and re-clone the repository. This is not what I'm looking for.

到目前为止,我尝试了什么,但是没有成功

What I tried so far but what not worked

git reflog expire --expire=all

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

Nothing happened so I tried to be clever and invoked the garbage collector

git gc --aggressive

但是假的.

推荐答案

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

You need, specifically, the --expire-unreachable option:

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

例如.

reflog 是用于引用的日志(因此名称为"reflog" :-)). 引用 ref 是一个以refs/开头的名称,例如refs/heads/master,这是分支名称master实际存储的方式.对于HEAD本身,还有一个额外的reflog,(因为它不是以refs/开头)在技术上不是我在

A reflog is a log for a reference (hence the name "reflog" :-) ). A reference or ref is a name beginning with refs/, such as refs/heads/master, which is how the branch name master is really stored. There is one extra reflog, for HEAD itself, which (since it doesn't start with refs/) is technically not a reference by the definition I linked in the gitglossary, but then, the glossary definition goes on to say that there are some special references that don't start with refs/, so either they're confused, or I am. :-)

无论如何,引用的重点是存储哈希ID(或者在特殊的HEAD引用的情况下,存储另一个引用的名称).哈希ID是一个值.您可以更新参考,从而更改存储的值-因此,随着时间的流逝,单个名称具有多个不同的值.有一个 current master,然后是前一个更改的master@{1}和前两个更改的master@{2},依此类推. (为保持一致性,您可以根据需要拼写当前值master@{0}.)所有内容均在

Anyway, the point of a reference is to store a hash ID (or in the case of the special HEAD reference, to store the name of another reference). A hash ID is a value. You can update a reference, which changes the stored value—so over time, the single name has taken on multiple different values. There's the current value master, and then there is the one from one change ago, master@{1}, and from two changes ago, master@{2}, and so on. (For consistency, you can spell the current value master@{0} if you like.) This is all spelled out in the gitrevisions documentation.

reflog 是Git保留上一个值的地方. reflog不仅存储先前的值,而且还存储值更改时的计算机时钟时间,因此Git可以处理master@{3.days.ago}之类的语法来查找master@{0}master@{1}master@{2}中的任何一项,表示三天前的值master. (三天"是指3天24小时制:72小时,无分钟,无秒,准确地说是259200秒前.如果昨天更改了master几次,则可能需要比master@{yesterday}更精确)

The reflog is where Git keeps the previous values. The reflog stores not only the previous value, but also the computer's clock-time when the value was changed—so Git can handle syntax like master@{3.days.ago} to find whichever entry, master@{0} or master@{1} or master@{2} or whatever, represents the value master had three days ago. ("Three days" means 3 24-hour days: 72 hours and no minutes and no seconds ago, or precisely 259200 seconds ago. If you changed master several times yesterday, you may need to be more precise than just master@{yesterday}.)

无论如何,假设master current 值是1234567...(有些丑陋的哈希ID),并且master@{1}8888888...master@{2}3333333....到目前为止,它们看起来都差不多.但是不一定如此:

Anyway, so, suppose that the current value of master is 1234567... (some big ugly hash ID), and that master@{1} is 8888888... while master@{2} is 3333333.... So far, they all seem rather alike. But they aren't necessarily so:

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

这里master@{1}master@{2}之间的区别-除了它们的值和大括号{}中的数字外,-重要git reflog expire的区别是我们可以<从master(1234567)开始并向后工作,找到了em> master@{1}.如果我们从master开始并返回一次提交,则我们来到master@{1}.如果我们再走一步,我们会得出无聊的提交o,我们甚至不知道其编号.我们跳过提交3333333.

The difference between master@{1} and master@{2} here—well, besides their values and the numbers inside the curly braces {}—the important difference to git reflog expire is that we can find master@{1} by starting from master (1234567) and working backwards. If we start at master and go back one commit, we come to master@{1}. If we go back another step we arrive at boring commit o whose number we don't even know; we skip right over commit 3333333.

具体地说,在这种情况下,从master的当前(1234567)值开始,master@{2}不可达.因此,它的到期时间是由--expire-unreachable参数控制的,而不是由--expire参数控制的.

Specifically, in this case, master@{2} is unreachable from the current (1234567) value of master. So its expiry is controlled by the --expire-unreachable argument, not by the --expire argument.

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

If you don't choose a particular value, git reflog will use the configured default, if you have configured one. In the absence of a configured default, the default defaults are 90 days for reachable entries and 30 days for unreachable entries. So:

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

是默认设置,除非您更改了自己的默认设置.如果您在命令行上覆盖了一个默认值,则将另一个默认值保留下来.

is the default, unless you've changed your own defaults. If you override one default on the command line, you leave the other default alone.

您的问题从一个重点开始:您做了很多基础工作. Rebase通过复制提交来工作,然后切换分支名称以使用新的(可能是经过改进的)提交.旧的仍然存在,并且从新的分支提示始终无法到达:

Your question starts with an important point: you did a lot of rebasing. Rebase works by copying commits, then switching branch names to use the new (and presumably improved) commits. The old ones are still around, and are invariably unreachable from the new branch tip:

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

其中,A--B--C是原始链(旧提交和棘手的提交),而A'-B'-C'是您想要的闪亮的新副本.由于连接总是向后进行,因此即使从其他引用中也可以访问旧分支,但是从新分支提示中总是无法访问这些旧连接.

where A--B--C is the original chain (the old and icky commits) and A'-B'-C' are the shiny new copies that you want. Since the connections always go backwards, the old ones are always unreachable from the new branch tips, even if they're reachable from some other references.

这篇关于GIT-删除旧的reflog条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆