我经常制作很多实验性代码,最终将其丢弃。在那段时间里,他们住在临时的Git回购中,后来我就吹走了。
或者,也许我应该创建一个分支,在那里做我的实验,然后删除分支。但是,分支占据的空间是否会被释放,或者历史保存到时间结束?
有时,远程仓库是在我无法控制的公司服务器上。因此,添加或删除repos往往是一项重量级的基于IT的操作。
答案 0 :(得分:5)
您需要定义一个"死分支"。更好的是,当你说"分支" -see 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实现中的{{3}}。根据定义,Git对象图是非循环的,因此引用计数在这里可以使用,但Git仍然使用标准的标记和扫描技术。这允许对象在创建后是只读的:不需要保留和更新引用计数。 Git只标记最初引用的对象,然后遍历图形以将标记复制到从这些对象引用的对象。
特别是,Git中的每个提交都列出了一些父提交的哈希ID - 通常只有一个,但是对于合并,两个或更多,对于root提交,没有父项。所以Git从所有外部引用开始 - 所有可以从外部内部图形直接访问的对象哈希ID - 然后,对于作为提交对象的每个对象,标记其父母,父母'父母等等。
在这种特殊情况下,对整个存储库数据库进行垃圾收集,Git还会标记每个树对象,并递归地标记每个可从树中访问的对象。这标记了所有使用的 blob 对象。 Git标记每个可直接访问的带注释标记,以及带注释标记对象本身指向的对象,以及递归地标记从该对象可到达的任何对象(带注释的标记可以指向四种对象中的任何一种)。
标记了每个可到达的对象后,所有剩余的对象都按照定义无法访问。 Git可以从存储库中弹出这些对象,重建压缩的包文件,它们存储应用了完全压缩的对象,然后删除任何过时的松散的对象(只有zlib压缩的对象) - 包文件中的完全压缩也会进行增量编码。
但我们仍然坚持使对象外部可以访问的问题,这就是分支名称,实际上所有名称都进入的地方。分支名称存在于refs/heads/
命名空间;标签名称位于refs/tags/
;远程跟踪名称存储在refs/remotes/
下,还有其他名称。总的来说,这些名称被称为 references ,它们都共享存储一个哈希ID的能力。
Git还将外部引用存储在:
HEAD
,当它被分离时,HEAD
(HEAD
的reflog有时被视为参考,有时不被视为参考; HEAD
文件,例如ORIG_HEAD
,MERGE_HEAD
和CHERRY_PICK_HEAD
; 如果对某些提交的唯一引用是其他提交,并且其他提交的唯一引用是分支名称及其reflog条目,并且 delete 分支名称,则在那点这两个提交现在是未引用的。他们有资格进行垃圾收集。还有一些额外的安全网:例如,它们的哈希ID可能存储在HEAD
reflog中。如果它们是松散的对象(尚未打包),则默认情况下会有14天的宽限期,从它们被删除之前的创建时间开始。此宽限期意味着Git命令最多需要14天才能完成其操作,即使垃圾收集过程已经开始,也会编写一个使新松散对象保持活动状态的引用。
Reflog条目最终到期,因此一旦删除了分支名称,该分支唯一的提交将不会超过任何HEAD
reflog条目(默认为30天)或14天的修剪宽限期,以较长者为准。在此之后,提交以及其他对象(树和blob)的存在以这些提交的继续存在为基础,可以随时删除,下一次垃圾收集 - 手动或自动 - 将删除它们。
答案 1 :(得分:3)
没有。分支只是提交中的标签。分支机构没有“历史”。有足够访问权限的人可以删除它。
如果你担心的是构成分支的提交,如果没有引用,最终它们可以被gc'ed。
答案 2 :(得分:0)
如果删除分支,那些提交的指针仍然存在于某个地方,从已删除分支合并的代码仍然存在。但随着时间的推移,垃圾收集将使删除的分支机构无法恢复"。有一些企业级工具可以帮助恢复已删除的分支。
可能重复:Does deleting a branch in git remove it from the history?