我是git的新手,并试图理解这些原则。据我所知,在Git中,每个文件都按照Git Book完全存储,也按照this post存储。但是,git book还指出了压缩二进制文件并计算文本文件差异的git gc,这个语句似乎与git存储完整文件的第一点相矛盾。
1)有人可以解释哪一个是正确的吗?如果git gc确实计算了部分差异,并且如果它经常在很长一段时间后运行,那么这是否会确保从基本版本到所有分支创建所有差异?如果没有定期运行git gc,这是否意味着大量的计算时间?
2)考虑像Android那样有大量源文件和资源文件的项目,似乎表明每次提交都会导致git大小爆炸。当开发人员拉动Android源代码时,如果它为所有源文件和二进制文件提取整个历史记录,是否会占用大量空间?我在这里错过了什么吗?这是如何长期持续的?
答案 0 :(得分:2)
Git是一个花哨的内容可寻址文件系统。 Notionally ,它存储每个修订版中每个文件的完整内容,并且每个blob(文件内容)都有一个可以检索的sha。在引擎盖下,git实际上能够将文件存储为类似文件的差异(通常是以前的版本,但不一定非必须),但这完全发生在git存储文件的最低级别。不仅git用户不必考虑它,即使大多数git 工具也不必考虑它。
至于size的问题,因为在“git filesstem”中存在各种形式的压缩,并且因为它们非常有效,所以.git
目录包含整个历史记录在项目达到数十万次提交之前,项目通常小于代码的单个签出。
如果存储库确实变得难以管理,那么(在git graft
之类的工具的帮助下)可以将项目的历史分成不同的存储库,沿着新/古历史或活动/存档分支,或类似的其他事情。
答案 1 :(得分:1)
git gc
计算存储差异的方式不一定与文件的历史记录有关。事实上,我记得在某个地方读书但目前找不到参考,它可能会为“基地”选择更多最近的修订版,因为那些是您最有可能检查的出。如果您有10,000个版本并且正在检出最新版本,则不希望将10,000个差异应用于版本1以获得所需的版本。
某些操作会自动运行git gc
。 pull
就是其中之一,所以你不可能在运行之间走很长时间。如果您愿意的话,没有什么能阻止您在每次提交后运行它。基本上这就是其他版本控制系统在幕后所做的事情,也是git速度如此之快的主要原因之一。
答案 2 :(得分:0)
git gc
用于清理/压缩存储库中的松散对象。它通过打包对象(文件/树/提交的每个完整状态)来完成此操作。差异可以从以前的文件创建,也可以来自完全不相关的文件,但具有类似的内容git。
为了解决问题2,如前所述,git会打包对象。虽然从概念上讲,每个文件都有完整的副本,但在运行gc
时它们会被打包。至于存储二进制文件,version control in general is not the best first choice.