为什么git会记录&x2014;所有显示已删除的提交?

为什么git会记录&x2014;所有显示已删除的提交?,git,Git,我在提交时使用了git reset--hard sha来剥离/删除几个提交,然后使用了git gc--prune=now。当我执行一个git log--pretty=oneline--abbrev commit时,它返回commits,其中包含我在reset命令中使用的sha的最新值。这就是我所期待的 然而,我随后做了git log--pretty=oneline--abbrev commit--all,它返回了我认为已剥离的提交。为什么这段历史还在这里 ETA:这些提交都不存在于主repo上。

我在提交时使用了
git reset--hard sha
来剥离/删除几个提交,然后使用了
git gc--prune=now
。当我执行一个
git log--pretty=oneline--abbrev commit
时,它返回commits,其中包含我在reset命令中使用的sha的最新值。这就是我所期待的

然而,我随后做了
git log--pretty=oneline--abbrev commit--all
,它返回了我认为已剥离的提交。为什么这段历史还在这里


ETA:这些提交都不存在于主repo上。
git log
命令的工作原理是从某个特定的提交或一组提交开始,其ID最终是原始OID,1然后通过提交图反向工作。2 OID来自给
git log
的参数;如果没有OID参数,也没有替代参数,默认情况下将
HEAD
作为OID查找。因此:

当我执行一个
git log--pretty=oneline--abbrev commit
时,它返回commits,其中包含我在reset命令中使用的sha的最新值。这就是我所期待的

很好。(顺便注意,
--oneline
--pretty=oneline--abbrev commit
的缩写,因此您可能希望使用它来缩短命令行序列。)

然而,我随后做了
git log--pretty=oneline--abbrev commit--all
,它返回了我认为已剥离的提交。为什么这段历史还在这里

--all
选项假装在命令行上指定了所有
refs/
条目(所有引用:所有分支名称、标记名称和其他非
HEAD
*\u HEAD
特殊名称的特殊名称)。这些引用中的一个或多个必须解析为或导致您认为已剥离的哈希

例如,
refs/stash
这样做,或者其他分支名称这样做,这并不罕见

您可以为每个ref运行
git,而不带任何参数,以列出
--all
所暗示的所有ref


现在最好不要把这些叫做“SHA”,因为至少在理论上,允许使用其他散列算法。确实,即将进行的更改是使用SHA2-256,它仍然是一个SHA散列,但内部Git术语现在是OID或对象ID


2使用
-g
-walk reflogs
),遍历是通过reflog,而不是提交图。使用
--no walk
时,walk本身被抑制,因此您只能获得最初选择的OID。

这是其中一种情况,在这种情况下,头发分割可能非常重要

当你说你“剥夺”了一些承诺,这是不准确的。更具体地说,在发出
reset
命令时,您从签出的分支的历史记录中删除了这些提交。如果任何其他ref(另一个分支、一个标记、当前存储、各种其他东西)可以到达这些提交,那么它仍然可以

git log的
--all
选项表示显示所有引用的历史记录,而不仅仅是当前分支(从中删除了提交)。您可以使用git log--graph--all的输出来分类哪些ref(s)仍然到达您的提交。如果您可以在您的环境中使用
gitk
,这可能是一种更好的可视化方法

另外,您的
gc
尝试将失败,即使没有ref仍然可以到达有问题的提交,因为reflog仍然可以到达它们。在移动所有ref之后,如果再也没有“知道”这些提交的内容,那么您还必须使任何受影响的reflog过期。

为每个ref运行
git--contains$removedsha
,以打印可从中访问已删除提交的所有ref。