在第一次克隆存储库期间,git首先接收对象(这很明显),然后花同样多的时间“解析增量”。在克隆的这个阶段到底发生了什么?
当前回答
Git使用delta编码在包文件中存储一些对象。但是,您不希望为了获得当前版本而必须回放给定文件上的每一次更改,因此Git还偶尔存储文件内容的快照。“解决增量”是处理确保所有这些保持一致的步骤。
这是Pro Git书中“Git内部”部分的一章,可以在网上找到,讨论了这个问题。
其他回答
Git使用delta编码在包文件中存储一些对象。但是,您不希望为了获得当前版本而必须回放给定文件上的每一次更改,因此Git还偶尔存储文件内容的快照。“解决增量”是处理确保所有这些保持一致的步骤。
这是Pro Git书中“Git内部”部分的一章,可以在网上找到,讨论了这个问题。
git克隆的阶段是:
接收repo数据库中所有对象的“pack”文件 为收到的包创建索引文件 检查头部修订(显然是针对非裸回购)
“解析增量”是第二阶段显示的消息,即索引包文件(“git index-pack”)。
包文件中没有实际的对象id,只有对象内容。因此,为了确定对象ID是什么,git必须对包中的每个对象执行解压缩+SHA1以生成对象ID,然后将其写入索引文件。
包文件中的对象可以存储为增量,即对其他对象所做的一系列更改。在这种情况下,git需要检索基对象,应用命令并SHA1结果。基对象本身可能必须通过应用一系列delta命令来派生。(即使在克隆的情况下,基本对象已经遇到了,但内存中缓存的人造对象数量是有限的)。
总之,“解析增量”阶段涉及到对整个回购数据库进行解压缩和校验,这并不奇怪,需要相当长的时间。据推测,解压和计算sha1实际上比应用delta命令花费更多的时间。
在后续获取的情况下,接收到的包文件可能包含对接收git预期已经拥有的其他对象的引用(作为增量对象基)。在这种情况下,接收git实际上重写了接收到的包文件,以包括任何此类引用的对象,因此任何存储的包文件都是自给自足的。这可能就是“解析delta”消息的来源。
Amber似乎在描述Mercurial或类似使用的对象模型。Git不会存储一个对象的后续版本之间的增量,而是每次存储该对象的完整快照。然后,它使用增量压缩来压缩这些快照,试图找到好的增量来使用,而不管这些增量在历史记录中存在的位置。
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别