我正在制作一门Git课程,想要提到失去的引用在运行git gc
之前并不是真正的丢失。但事实并非如此。即使在运行git gc --prune=all --aggressive
之后,这些失去的引用仍然存在。
显然,我理解错了什么。在课程中说错话之前,我想搞清楚事实!下面是一个示例脚本,说明了这种效应:
#!/bin/bash
git init
# add 10 dummy commits
for i in {1..10}; do
date > foo.txt
git add foo.txt
git commit -m "bump" foo.txt
sleep 1
done;
CURRENT=$(git rev-parse HEAD)
echo HEAD before reset: ${CURRENT}
# rewind
git reset --hard HEAD~5
# add another 10 commits
for i in {1..10}; do
date > foo.txt
git add foo.txt
git commit -m "bump" foo.txt
sleep 1
done;
这个脚本将添加10个虚拟提交,回退到5个提交之前并再次添加10个提交。在重置之前,它会打印出当前HEAD的哈希值。我期望运行
git gc --prune=all
后丢失CURRENT
中的对象。但是,我仍然可以对该哈希运行git show
命令。我知道,在运行
git reset
和添加新提交后,我实际上创建了一个新分支。但是我的原始分支已经没有任何引用了,因此它不会显示在git log --all
中。它也不会被推送到任何远程分支。我理解
git gc
的作用是删除这些对象。但事实并非如此。为什么?那么,
git gc
什么时候会删除对象呢?
git reflog --expire=all
命令。然后这个对象仍然存在。接下来我又运行了另一个gc
命令,但它仍然存在。即使运行了另一个git gc --aggressive --prune=all
命令也没有帮助。 - exhuma--expire=all --all
,或在HEAD
(默认)和master
上运行它。或者您可以手动删除特定条目(或参见下面的答案)。 - torek