git重传到期,git fsck--无法到达?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (36)

所以我在玩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

这意味着我做了两次提交(da8534a5a1e68a),然后第三次提交ff576c1我用4eea1cd...

就像预期的一样,我的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分支。

知道怎么回事吗?

我只是注意到如果我加上--rewrite选择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.

在我的案子里这是不合理的。好吧,至少我不明白,因为很明显是吗?改变一些东西。

提问于
用户回答回答于

这种行为来自于REFLOG设计理念与垃圾收集需求之间的交互。

为了让垃圾收集器安全地删除COMMIT,必须删除对该提交的所有引用--包括reflg条目中的引用。尽管reflog show,每个reFlog条目实际上包含两个SHA 1标识符:更改前的ref值和更改后的ref值。为了确保安全的垃圾收集,reflog expire只需删除两个SHA 1中的一个标识不可访问提交的条目。

在你的情况下,最近的REFLOG条目的更改前值是指不可访问的提交。即使修改后的值所标识的提交仍然是可达的,reflog expire删除条目。

该设计实现简单,结果是日志不完整,但精确。

--rewrite期权

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

  • 在日志中留下了一个缺口。
  • 与可达提交相关的有用信息丢失。

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

  • 和前面一样,删除了那些由更改后SHA 1标识的提交不可访问的条目。
  • 更改前提交不可达的条目被修改,以弥补已删除条目留下的空白(更改前SHA 1被设置为前一项的更改后SHA 1的值)。

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

扫码关注云+社区