git - repo 历史上Git中枯死的 Twig 会永远存在吗?

标签 git

我经常设计很多实验性的代码,但最终还是丢掉了。在这段时间里,他们住在我后来吹走的临时git回购中。
或者,我应该创建一个分支,在那里做实验,然后删除该分支。但是,这个分支所占据的空间有没有被释放过,或者说这段历史是否被保存到了时间的尽头?
有时,远程回购是在一个我不控制的公司服务器上。因此,增加或删除回购协议往往是一项重量级的基于it的操作。

最佳答案

你需要定义一个“死树枝”。更好的方法是,先弄清楚你说“分支”是什么意思-参见What exactly do we mean by "branch"?
作为bmargulies noted,如果提交没有引用,它最终将被垃圾回收。所以一个更精确的问题是:提交何时有引用?
如果您熟悉lisp或任何更现代的垃圾收集语言(包括go、java和python),那么您在这里有一个很大的起点。如果没有,请阅读Wikipedia page。注意,通用语言收集器必须处理cycles in the object graph, which create problems for simple reference-counting collectors的问题,例如在cpython实现中。git对象图在定义上是非循环的,因此引用计数在这里可以工作,但是git仍然使用标准的标记和扫描技术。这允许对象在创建后是只读的:不需要保留和更新引用计数。git只是简单地标记最初引用的对象,然后遍历图形,将标记复制到从这些对象引用的对象。
特别是,git中的每个提交通常只列出一组父提交的hash id,但对于合并,则列出两个或更多,对于根提交,则不列出父提交。因此git从所有外部引用开始,所有可以从内部图外部直接访问的对象散列id,然后,对于作为commit对象的每个对象,标记其父对象、父对象等等。
在这种特殊情况下,对于垃圾收集整个存储库数据库,git还标记每个树对象,并且递归地标记每个可从树访问的对象。这将标记所有已使用的blob对象。git标记每个可直接访问的带注释标记,加上带注释标记对象本身指向的对象,以及递归地标记任何可从该对象访问的对象(带注释标记可以指向四种对象中的任何一种)。
在标记了每个可到达的对象之后,根据定义,所有剩余的对象都是不可到达的。git可以从存储库中弹出这些对象,重新生成压缩包文件,这些压缩包文件存储应用了完全压缩的对象,然后删除任何过时的松散对象(它们只是zlib压缩的,包文件中的完全压缩也执行增量编码)。
但是,我们仍然无法确定是什么使对象可以外部访问,这就是分支名称,实际上是所有名称的来源。分支名称存在于refs/heads/命名空间内;标签名存在于refs/tags/;远程跟踪名称存储在refs/remotes/下,还有其他名称。总的来说,这些名称称为引用,它们都共享存储每个散列ID的能力。
Git还将外部引用存储在:
reflogs,保留引用名称的先前值;
HEAD,当它被分离时,HEAD的重新记录(HEAD有时被视为参考,有时不被视为参考);
其他特殊的HEAD文件,如ORIG_HEADMERGE_HEADCHERRY_PICK_HEAD
索引,通常包含blob引用;以及
添加了工作树索引文件。
如果对某个提交的唯一引用是另一个提交,而该另一个提交的唯一引用是分支名称及其reflog条目,并且删除了分支名称,则此时这两个提交现在未被引用。他们有资格收垃圾。有一些额外的安全网:例如,它们的hash id可能存储在HEADreflog中。如果它们是松散的对象(尚未打包),则它们有一个宽限期,默认为14天,从它们被移除之前创建的时间算起。这个宽限期意味着git命令有14天的时间来完成它们的操作,编写一个引用来保持一个新的松散对象的活动,即使垃圾收集过程已经启动。
reflog条目最终会过期,因此一旦删除分支名称,该分支唯一的提交将不会比任何HEADreflog条目(默认情况下为30天)或14天的prune宽限期(以较长者为准)长。在此之后,提交,以及任何其他对象(树和斑点)的存在,这些预测是基于这些提交的继续存在,准备好移除,并且下一个垃圾收集手册或自动删除它们。

关于git - repo 历史上Git中枯死的 Twig 会永远存在吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50340329/

相关文章:

git - 初始提交后如何在 Git 存储库中创建 "master"分支?

Git:无法 checkout 分支 - 错误:pathspec '...' 与 git 已知的任何文件都不匹配

git - 如何更新一个子模块 git?

git - 我可以像 git 一样跳过 Mercurial 预提交钩子(Hook)吗?

Git 搜索所有差异

windows - 错误!在 $PATH 中找不到 git 二进制文件

git reset - 忽略特定的未跟踪文件

git - heroku 应用程序上的应用程序错误

git - Netbeans:COMMIT [HEAD] 不存在

git - 如何删除分支及其引用的所有对象