前言
在 Git 中只要提交记录产生,无论你是 reset
、 rebase
还是 commit --amend
等操作都没事,最终都能在 git reflog
中找到。那么问题来了,reflog 为什么能够找到?
HEAD 指针
首先,要明白提交的 commit 纪录一旦产生就一直都在,无论是 reset 还是 rebase 等操作并没有对 commit 纪录进程删除和更改,只是修改了指向 commit 的 HEAD 指针而已。
是否真的丢弃了 commit
当我们通过 git commit --amend
或 git 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 平时放着没事,如果太多当你做一些 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