git reflog过期和git fsck –unreachable

免责声明:此问题纯粹是信息性的,并不代表我遇到的实际问题。我只是想为了找出东西(因为我喜欢弄清楚东西,我也知道你也这样做)。

所以我正在玩git,试图过期修改提交。我的反垃圾邮件看起来像这样:

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

这意味着我做了两个提交(da8534a和5a1e68a),然后是第三个提交ff576c1,我用4eea1cd修改。

正如预期的那样,我的git日志看起来像这样:

* 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过期:

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

那时候,给我的是:

would prune commit: test: bar
would prune commit (amend): amend commit

起初我虽然我的HEAD没有引用大师,但正如你在git日志输出中可以看到的,我刚才提到,它实际上是。此外,cat .git / HEAD也确认(yelding ref:refs / heads / master)。无论如何,即使是愚蠢的,因为4eea1cd是我的主分支的头。

所以在这里我都感到困惑,这两个命令不会给我相同的提交,并且想知道如何可能4eea1cd可能无法访问,因为它是我的主分支的实际提示。

关于发生什么的任何想法?

编辑:我刚刚注意到,如果我添加了-rewrite选项到git reflog过期,就像这样:

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

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

would prune commit: test: bar

我还是不明白,因为根据git帮助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.

这在我的情况下没有意义。至少我没有得到它,因为它显然改变了一些东西。

这种行为来自于反垃圾邮件设计理念和垃圾收集要求之间的交互。

对于垃圾回收器安全删除的提交,所有对该提交的引用必须被删除 – 包括reflog条目中的引用。尽管出现reflog显示,每个reflog条目实际上包含两个SHA1标识符:更改前的引用的值和更改后的引用的值。为了确保安全的垃圾回收,reflog到期只会删除其中两个SHA1中的一个标识不可达的提交的任何条目。

在您的情况下,最近的reflog条目的改变前值是指不可达的提交。即使由变更后值确定的提交仍然可以访问,因此reflog到期将删除条目。

这种设计实现简单,导致不完整但准确的日志。

–rewrite选项

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

>日志中留下一个空白
>与可访问的提交有关的有用信息将丢失

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

>像以前一样,删除由SHA变为SHA1标识的提交不可达的条目。
>改变前提交不可访问的条目被修改以弥合删除的条目留下的空白(预先更改的SHA1被设置为上一个条目的变更后SHA1的值)。

不幸的是,修改条目会导致不再准确地反映参考文献的日志。例如,更改原因可能在重写后不再有意义。这就是为什么–rewrite不是默认的。

http://stackoverflow.com/questions/9184344/git-reflog-expire-and-git-fsck-unreachable

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:git reflog过期和git fsck –unreachable