Git "浅克隆+取消浅克隆" vs "普通克隆"

4

我看到了这个有关git克隆错误的答案,建议不要克隆整个存储库,而是只克隆最新提交,然后使用unshallow获取其余提交。

考虑下面的两个命令:

1. 
git clone <url> --depth 1
git fetch --unshallow

并且

2. 
git clone <url>

克隆的最终输出是否相同?如果是这样,那么第二个命令为什么比第一个在处理非常大的存储库时快得多?

浅层克隆是否还有其他未执行的操作或者在处理大型存储库时存在某些缺点?


克隆的存储库有多大? - evolutionxbox
就大小而言,大约有10GB以上的数据。我还更新了问题,以包括同一问题中大型和小型repo之间的区别。 - twothreezarsix
请注意,您在一个问题中提出了四个问题。 - evolutionxbox
我会删除最后的编辑。 :) - twothreezarsix
1个回答

6
当你克隆一个非常大的仓库时,需要传输大量数据。根据您的网络速度,这可能需要很长时间。举个例子,假设总共的数据传输大小为10 GiB(数据传输大小和磁盘上的大小不同,但通常差别不大),并且假设您可以获得1 MiB/s的传输速率。那么数据传输需要10240 MiB /(1 MiB/s)= 10240秒 = 170.667分钟 = 稍低于3小时(约2小时50分钟)。
尽管使用的各种协议都具有错误检测和(通常在硬件级别上)纠正功能,但在此期间仍存在连接失败的风险。如果连接失败,则git clone将整个过程视为原子操作:没有任何操作成功,因此Git将删除整个克隆。
如果使用--depth 1进行获取会导致初始克隆只复制大约总数据的1/3,我们的克隆时间将减少到大约1小时,同时也降低了完全失败的风险。然后可以增量添加到浅克隆中(使用--deepen或更大的--depth数字来git fetch)。每个命令都有其自身的失败风险,但失败只会导致不添加对象:现有的克隆不会受到损害。根据需要重试一个小时的传输要比重新启动整个3小时的传输(只为在2小时20分钟后失败)要容易得多。
最终,--unshallow可以获取您本来可以一次性无错地进行完整克隆得到的所有内容。请注意,在初始浅克隆期间可能需要使用--no-single-branch,或者在初始浅克隆之后修复获取refspec。

两种方法的最终输出是否相同?

答案既是“否”也是“是”。我们需要明确定义“最终输出”的精确含义。但就访问所有提交和其他对象的有用性而言,结果是相同的(前提是您撤消--depth选项的单分支效果)。

如果是这样,第二个命令如何比第一个快得多?

它不一定加快速度。然而,在进行全克隆时,Git可以发送现有的pack文件,而不是构建新文件。

这可以节省发送方的CPU时间。如果发送方上的单个pack文件构造良好,则接收方上的结果也将构造良好。

通过浅克隆重复深化,甚至是单个取消深化,得到的结果通常是接收方上的多个pack文件;这些文件可能没有那么完整。


1我从实际经验中说话。:-) 现在传输速率比2005年脆弱的DSL电线时要快,但存储库现在更大了。即使现在,美国某些地区的互联网基础设施也很糟糕。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接