我注意到在我在Git中压缩了一堆提交后,我仍然可以查看各个提交。被其他所有其他提交压缩的提交之一是使用提交消息引用其还原的提交的哈希值进行恢复。在此哈希上执行git show
向我显示此提交的确切内容。这个提交在我的历史中没有任何地方,因为它被压缩成一个提交。
这怎么可能?这仍然在DAG的某个地方吗?当git gc
之类的东西运行时,Git最终会被垃圾收集吗?
答案 0 :(得分:2)
是的:每当你在Git中做任何事情时,你真的将新对象(提交和文件等)添加到存储库,保留现有对象。主要的例外是git gc
,但即使这样就会使现有对象一直存在,直到它们过期。
确切的到期时间有点复杂。所有对象通常至少存活两周,以便在慢速操作期间不会被移除(可能需要几秒甚至几分钟,在此期间不会记录任何对象)。
除此之外,写入引用的对象ID(主要是提交ID) - 例如分支上的提交,或记录在HEAD
中 - 通常也会写入每个分支的 reflog ( HEAD
)有一个单独的日志。这些条目在写入时带有时间戳,默认情况下这些条目可以存活30天或90天。那些寿命更长的是从引用的提示可以的那些:对于HEAD
,提交仍然在HEAD
的历史中的提交,以及分支机构,仍然在分支上的提交。寿命较短,30天到期的提交是那些不再在分支机构上的(例如,已被重新定位和/或压扁)。
这些reflog条目用于保护Grim Reaper 收集器中的对象。所以这意味着你的旧提交将持续30天,而不仅仅是所有事情的14天。
删除引用(例如git branch -D branch
)也会导致其reflog被删除。因此,如果reflog条目仅在已删除的分支中,则宽限期可能会缩短到距离对象创建的14天。
重新提交的提交仍然由特殊名称ORIG_HEAD
引用,直到某些内容(通常是另一个rebase)覆盖ORIG_HEAD
。因此,这可能会保护提交超过30天的默认值。
直到git gc
实际运行并移除一个对象,但它会一直存在。它通常不会被复制到克隆,但如果git gc
永远不需要运行,它可能仍然存在于您的存储库中,可以访问多年。