我有一个小的回购,有几个提交:
* a0fc4f8 (HEAD -> testbranch) added file.txt
* e6e6a8b (master) hello world now
* f308f53 Made it echo
* f705657 Added hello
* 08a2de3 (tag: initial) initial
另外:
$ git status
On branch testbranch
nothing to commit, working directory clean
我无法理解以下行为。在这种状态下,我运行:
$ git reset initial
我现在看到了:
* e6e6a8b (master) hello world now
* f308f53 Made it echo
* f705657 Added hello
* 08a2de3 (HEAD -> testbranch, tag: initial) initial
我的期望:提交a0fc4f8将被删除,因为它无法访问
发生了什么:
1)执行git show a0fc4f8
仍然显示提交
2)执行git status
显示通过提交a0fc4f8添加的file.txt
为未跟踪,并且由提交f705657添加的文件hello也显示为未跟踪。
3)运行git gc
或git gc --prune=all
不会删除a0fc4f8,尽管它不再可用,并且没有与之关联的名称/标签。
为什么会发生这种情况?
更新:
$ git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (15/15), done.
更新2:
$ git log --all --decorate --graph --oneline
* e6e6a8b (master) hello world now
* f308f53 Made it echo
* f705657 Added hello
* 08a2de3 (HEAD -> testbranch, tag: initial) initial
$ git gc --force
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (15/15), done.
Total 15 (delta 1), reused 15 (delta 1)
$ git log --all --decorate --graph --oneline
* e6e6a8b (master) hello world now
* f308f53 Made it echo
* f705657 Added hello
* 08a2de3 (HEAD -> testbranch, tag: initial) initial
$ git show a0fc4f8仍显示提交
更新3:
$ git reflog testbranch
08a2de3 testbranch@{0}: reset: moving to initial
a0fc4f8 testbranch@{1}: commit: added file.txt
e6e6a8b testbranch@{2}: branch: Created from HEAD
答案 0 :(得分:6)
1)做
git show a0fc4f8
仍然显示提交
这是设计的。由于以下几个原因,不会立即删除无法访问的对象:
不时会自动修剪无法访问的对象。它也是由一些git命令执行的(fetch
和push
是其中的一部分。)
2)执行
git status
会将提交file.txt
添加的a0fc4f8
显示为未跟踪,并且提交hello
添加的文件f705657
也会显示没有跟踪。
您在未指定模式的情况下运行git reset
。默认模式为--mixed
,表示:
initial
); 这解释了为什么文件在目录(第三个项目符号)中以及它们未被跟踪的原因(第二个项目符号;索引与initial
提交相匹配,但这些文件在它不存在时甚至不存在创建)。
3)正在运行
git gc
或git gc --prune=all
不会删除a0fc4f8
,但它不再可以访问,并且没有与之关联的名称/标记。
git gc
还检查分支reflogs以获取引用。如果您的testbranch
分支已启用reflog
,那么reflog中的最新条目将指向提交a0fc4f8
(这是testbranch
分支在您运行{{1}之前的位置}})。您可以通过运行git reset
来检查是否为分支testbranch
启用了reflog。如果它打印了某些内容,您将在第二行的git reflog testbranch
位置找到提交a0fc4f8
。符号name@{n}
表示分支testbranch@{1}
的先前n
th 值(它指向的提交,name
过去移动)。
您可以在git gc
找到有关documentation工作方式的更多信息。
在 Notes 部分中,它显示为:
n
非常努力地保护它收集的垃圾。特别是,它不仅会保留当前分支和标记集引用的对象,还会保留索引引用的对象,远程跟踪分支,git gc
中git filter-branch
保存的引用或reflogs(这可能会引用后来修改或重绕的分支机构的提交。)如果您希望收集某些对象而不是这些对象,请检查所有这些位置,并确定在您的情况下删除这些引用是否有意义。