丢弃的 commit 去哪了

243 阅读1分钟

丢弃的 commit 去哪了

前言

在 Git 中只要提交记录产生,无论你是 resetrebase 还是 commit --amend 等操作都没事,最终都能在 git reflog 中找到。那么问题来了,reflog 为什么能够找到?

HEAD 指针

首先,要明白提交的 commit 纪录一旦产生就一直都在,无论是 reset 还是 rebase 等操作并没有对 commit 纪录进程删除和更改,只是修改了指向 commit 的 HEAD 指针而已。

是否真的丢弃了 commit

当我们通过 git commit --amendgit rebase 创建一个新的提交或者通过 git reset --hard HEAD^ 撤销 commit 时,旧的提交仍然保留着呢。您通过 git log 看不到它们的原因是因为没有指向它们的指针,这些 commit 就是 dangling commit(悬挂的 commit)。

dangling commit

你可以通过 git fsck --lost-found 命令查看 dangling commit 列表。

例如,我们通过 git reset --hard HEAD^ 撤销 commit 产生了 dangling commit,然后通过 git fsck --lost-found 命令查看 dangling commit 列表:

dangling commit

这些 dangling commit 平时放着没事,如果太多当你做一些 git 操作的时候,比如大量的 dangling commit 导致 git rebase 出现如下提示:


Auto packing the repository in background for optimum performance. See "git help gc" for manual housekeeping. error: The last gc run reported the following. Please corrent the root cause and remove .git/gc.log. Automatic cleanup will not be performed until the file is removed. warning: There are too many unreachable loose objects; run 'git prune' to remove them.

这时你就得手动删除了,也很简单:

git reflog expire --expire=now --all
git gc --prune=now