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改变一些东西。

时间:原作者:0个回答

101 5

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

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

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

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

--rewrite 选项

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

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

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

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

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

原作者:
...