我在一次提交中使用git reset --hard sha
来剥离/删除几个提交,然后使用git gc --prune=now
。当我执行git log --pretty=oneline --abbrev-commit
时,它会返回提交,最新提交时间为我在重置命令中使用的sha。这正是我所期待的。
然而,我随后执行了git log --pretty=oneline --abbrev-commit --all
,它正在返回我认为已剥离的提交。为什么这段历史还在这里?
ETA:主回购上不存在这些提交
在这种情况下,分叉可能非常重要。
当你说你";剥离的";有些提交是不精确的。更具体地说,当您发出reset
命令时,您从签出的分支的历史记录中删除了这些提交。如果任何其他ref(另一个分支、一个标记、当前存储、各种其他东西(都可以到达这些提交,那么它仍然可以。
git log
的--all
选项表示显示所有引用的历史记录,而不仅仅是当前分支(从中删除了提交(。您可能能够使用git log --graph --all
的输出来排序哪些ref(s(仍然到达您的提交。如果您可以在您的环境中使用gitk
,这可能是一个更好的可视化。
另外需要注意的是,即使没有refs仍然可以到达有问题的提交,您的gc
尝试也会失败,因为reflog仍然可以到达它们。在移动所有参考文献使得没有任何"参考文献"之后;知道";在这些提交中,您还必须使任何受影响的reflog过期。
git log
命令的工作原理是从某个特定的提交或一组提交开始,这些提交的ID最终是原始OID,1,然后在提交图中反向工作2OID来自给git log
的自变量;由于没有OID参数,也没有它们的替代品,默认情况是将HEAD
查找为OID。所以这个:
当我执行
git log --pretty=oneline --abbrev-commit
时,它会返回提交,最新提交次数为重置命令中使用的sha。这正是我所期待的。
很好。(顺便注意,--oneline
是--pretty=oneline --abbrev-commit
的缩写,所以您可能想用它来缩短命令行序列。(
然而,我随后执行了
git log --pretty=oneline --abbrev-commit —-all
,它正在返回我认为已剥离的提交。为什么这段历史还在这里?
--all
选项假定在命令行上指定了所有refs/
条目(所有引用:所有分支名称、标记名称和其他非HEAD
或*_HEAD
特殊名称的特殊名称(。这些裁判中的一个或多个必须下定决心,或者导致你认为自己被剥夺了资格。
例如,refs/stash
或其他分支名称这样做并不罕见。
您可以运行完全不带参数的git for-each-ref
来列出--all
所暗示的所有引用。
1最好不要把这些称为";SHA";现在,至少在理论上允许使用其他哈希算法。的确,即将到来的更改是使用SHA2-256,它仍然是一个SHA哈希,但内部Git术语现在是OID,或对象ID。
2对于-g
(--walk-reflogs
(,遍历是通过reflog而不是提交图。使用--no-walk
时,漫游本身将被抑制,因此您只能获得最初选择的OID。