git“浅克隆+非浅”与“正常克隆”

two*_*six 4 git git-clone

我已经看到了git clone error 的答案,其中建议不要克隆整个存储库,而是仅克隆最新的提交,然后使用 unshallow 来获取其余的提交。

考虑以下两个命令

1. 
git clone <url> --depth 1
git fetch --unshallow
Run Code Online (Sandbox Code Playgroud)

2. 
git clone <url>
Run Code Online (Sandbox Code Playgroud)

两者克隆的最终输出是否相同?如果是这样,对于一个非常大的存储库,第二个命令的运行速度为何比第一个命令快得多?

浅层克隆是否还有其他一些不做的事情,或者有一些缺点,特别是在使用大型存储库时?

tor*_*rek 7

当您克隆非常大的存储库时,您需要传输大量数据。根据您的网络速度,这可能需要很长时间。为了给出一些具体的数字,我们使用 10 GiB 作为总体存储库数据传输大小(数据传输大小和磁盘大小会有所不同,但通常相差不是很大),并假设您可以获得的传输速率为1 MiB/秒。这意味着数据传输需要 10240 MiB / (1 MiB/s) = 10240 秒 = 170.667 分钟 = 略低于 3 小时(约 2 小时 50 分钟)。

\n

使用的各种协议都内置了错误检测和(通常在硬件级别)纠正功能,但在此期间连接仍然有可能失败。如果连接确实失败,git clone则将整个事情视为原子:所有事情都不起作用,因此 Git 将删除整个克隆。

\n

如果使用 fetch--depth 1导致初始克隆仅复制大约 1/3 的整体数据,我们会将克隆时间缩短至大约 1 小时,从而降低完全失败的风险。然后可以逐步添加到浅克隆(使用--deepen或更大的--depth数字git fetch)。其中每一个都有自己的失败风险,但失败只会导致不添加任何对象:现有的克隆不会受到损害。根据需要重试一小时的传输比重新启动整个 3 小时的传输却在 2 小时 20 分钟内失败要轻松得多。1

\n

最终,--unshallow如果你能够一次完成完整的克隆而不会出现错误,那么最终的结果将给你带来你所能得到的一切。请注意,您可能希望--no-single-branch在初始浅克隆期间使用,或者在初始浅克隆之后修复获取引用规范。

\n
\n

两者克隆的最终输出是否相同?

\n
\n

答案既是否定的,又是肯定的。我们需要准确地定义“最终输出”的含义。不过,就对所有提交和其他对象的有用访问而言,结果是相同的(前提是您撤消参数的单分支效果--depth)。

\n
\n

如果是这样,对于一个非常大的存储库,第二个命令的运行速度为何比第一个命令快得多?

\n
\n

它不一定工作得更快。然而,在进行完整克隆时,Git 可以 \xe2\x80\x94 不一定这样,但可以\xe2\x80\x94 只是发送一个现有的包文件,而不是构建一个新的包文件。这可以节省发送端的CPU时间。如果发送方上的(单个)包文件构造良好,则接收方上生成的单个包文件也构造良好。使用浅克隆甚至单个非浅克隆进行重复加深的结果通常会是接收器上的多个包文件;这些可能结构不那么好。

\n
\n

1我在这里讲的是实际经历。:-) 现在的传输速率比 2005 年片状 DSL 线路更高,但存储库也更大。而且,即使是现在,美国某些地方的互联网基础设施也很糟糕。

\n