git - 可以到达的git reflog过期和 git

  显示原文与译文双语对照的内容
107 2

免责声明:这里问题纯粹是信息,不代表我遇到的实际问题。 我只是想为( 因为我喜欢 figuring,而且我知道你也这么做) 找到一些东西。

所以我正在玩 git,试图使修改后的提交失效。 我的reflog看起来像:


4eea1cd HEAD@{0}: commit (amend): amend commit


ff576c1 HEAD@{1}: commit: test: bar


5a1e68a HEAD@{2}: commit: test: foo


da8534a HEAD@{3}: commit (initial): initial commit



这意味着我做了两个提交( da8534a5a1e68a ),然后是第三个提交 ff576c1

就像预期的那样,我的git log 看起来类似于:


* 4eea1cd (HEAD, master) amend commit


* 5a1e68a test: foo


* da8534a initial commit



我知道关于提交的,某一天( 很可能在 30天内,默认情况下) git gc 应当收集 ff576c1 。 现在我不想等待 30天才能看到这种情况,所以我开始运行一些命令,首先:


git fsck --unreachable --no-reflogs



就像我再次期望的那样


unreachable blob 5716ca5987cbf97d6bb54920bea6adde242d87e6


unreachable tree 1e60e555e3500075d00085e4c1720030e077b6c8


unreachable commit ff576c1b4b6df57ba1c20afabd718c93dacf2fc6



所有的信心我都要过期,这个不足的ff576c1 提交,然后运行 git reflog expire:


git reflog expire --dry-run --expire-unreachable=now --all



那时候,我就知道了:


would prune commit: test: bar


would prune commit (amend): amend commit



最初我的HEAD 没有引用 master,但是就像你在前面的git log 输出中所看到的,实际上它是。 另外 cat. git/HEAD 确认了( yelding ref: refs/heads/master ) 。 尽管如此,虽然 4eea1cd 是我的master 分支的头,但它还是愚蠢的。

因这里,这两个命令都不会给我相同的提交,因为 4eea1cd 是我的master 分支的实际提示。

关于接下来发生的事情?

如果我将选项添加到 git reflog expire 中,我就会注意到 :


git reflog expire --dry-run --expire-unreachable=now --all --rewrite



然后我只得到修改过的提交:


would prune commit: test: bar



我仍然不明白,因为根据 git help reflog:


 --rewrite


 While expiring or deleting, adjust each reflog entry to ensure that


 the old sha1 field points to the new sha1 field of the previous


 entry.



在我看来这并没有什么意义。 至少我不明白,因为 obvisouly 英镑做something改变一些东西。

时间: 原作者:

101 5

这种行为来自reflog设计哲学与垃圾收集需求之间的交互。

对于垃圾收集器安全删除的提交,所有对该提交的引用都必须是reflog条目中的deleted—including引用。 尽管 reflog show 出现,每个reflog条目实际上包含两个SHA1标识符: 更改前的引用值和更改后引用的值。 为了确保垃圾回收,reflog expire 只删除两个SHA1s中的一个,其中一个标识不可达的提交。

在你的情况下,最近的reflog条目的预期更改值引用不可以访问的提交。 即使由post更改值标识的提交仍然可以访问,reflog expire 也会删除条目。

这种设计易于实现,并产生一个不完整但准确的日志。

--rewrite 选项

不幸的是,删除一个引用仍然可以达提交的条目有两个问题:

  • 日志中留下了空白。
  • 仍可以访问的提交相关的有用信息丢失

通过以下方式更改行为,--rewrite 选项可以解决这些问题:

  • 以前一样,无法删除由post更改SHA1标识的提交的条目。
  • 修改预先更改提交的条目将被修改以桥接删除的条目( 预先更改SHA1被设置为前一次输入SHA1的日志更改值) 所留的间隙。

不幸的是,修改条目会导致日志不再准确反映引用的历史。 例如更改原因可能不再是重写之后的意义。 这就是为什么 --rewrite 不是默认的原因。

原作者:
...