Git Travis和其他CI服务上浅层克隆的缺点?

Git Travis和其他CI服务上浅层克隆的缺点?,git,continuous-integration,travis-ci,shallow-clone,appveyor,Git,Continuous Integration,Travis Ci,Shallow Clone,Appveyor,大多数CI服务都提供了一种浅层克隆存储库的方法。例如,在Travis上: git: depth: 1 或在验船师处: clone_depth: 1 or shallow_clone: true Build started git clone -q --depth=1 --branch=<branch_name> https://github.com/<user>/<repo_name>.git C:\projects\<repo_name>

大多数CI服务都提供了一种浅层克隆存储库的方法。例如,在Travis上:

git:
  depth: 1
或在验船师处:

clone_depth: 1
or
shallow_clone: true
Build started
git clone -q --depth=1 --branch=<branch_name> https://github.com/<user>/<repo_name>.git C:\projects\<repo_name>
git checkout -qf 53f3f9d4d29985cc6e56764c07928a25d94477ed
fatal: reference is not a tree: 53f3f9d4d29985cc6e56764c07928a25d94477ed
Command exited with code 128
这具有明显的速度优势,因为您不必克隆整个存储库


在CI服务上进行浅层克隆有什么缺点吗?是否存在浅层克隆会导致CI生成失败的情况?否则,为什么不将浅层克隆作为这些CI服务的默认设置?

通常不会发生这种情况的原因有两个

首先,浅层克隆的散列将不同于存储库中的任何版本。因此,不可能跟踪您已完成的构建以获得任何特定结果

其次,如果您没有详细信息,大多数Git服务器都能够发送经过优化的“everything.pack”。否则,服务器将不得不提供一个自定义提交包,其中只包含要发送给您的浅层副本。因此,尽管可能会有更多的数据通过网络传输,但实际上可能会导致服务器上的更多工作


最后,相当多的CI构建将执行某种类型的标记操作并将其上载到存储库,而您实际上无法标记浅层克隆(请参见第1点)。

添加到AlBlue的答案中:

另一个问题是克隆深度设置也用于git子模块

在使用git子模块的项目中,Travis等将从master开始克隆子模块repo,然后签出特定版本

如果子模块中指向的提交不在当前主模块的n个提交范围内(其中n是深度设置),则它将无法签出。

默认行为和选项 在Travis CI上,默认行为是使用50的克隆深度。
:

在AppVeyor上,默认设置是克隆整个存储库。
AppVeyor提供了设置克隆深度和一个可选的
shallow\u clone:true
选项,其中提交使用GitHub或Bitbucket API作为zip存档下载。()

中的描述:

不要在CI项目中使用深度=1! 在CI平台开始克隆预期提交之前,如果将新提交推送到分支,则使用
(克隆)深度:1
通常会导致git错误。 在AppVeyor和TravisCI上,都可以正常地将操作推送到GitHub上的存储库

AppVeyor上失败签出的输出示例:

clone_depth: 1
or
shallow_clone: true
Build started
git clone -q --depth=1 --branch=<branch_name> https://github.com/<user>/<repo_name>.git C:\projects\<repo_name>
git checkout -qf 53f3f9d4d29985cc6e56764c07928a25d94477ed
fatal: reference is not a tree: 53f3f9d4d29985cc6e56764c07928a25d94477ed
Command exited with code 128
我没有发现使用
shallow\u clone:true
设置的项目有任何问题

重新启动基于旧提交的构建 使用有限深度时的第二个结果是,当超出此范围时,在旧提交上重新启动CI生成将失败

忠告 在AppVeyor上,如果存储库在GitHub或Bitbucket上可用,我建议使用
shallow\u clone:true
。 除非您想对代码执行git操作,否则这似乎是最好的选择

在TravisCI上,不设置深度(并使用默认深度50)似乎是合理的。 如果不希望触发历史构建或基于存储库上的流量进行优化,则可以使用不同的值

克隆依赖项 外部依赖项通常由分支或标记引用。
获取分支尖端或克隆标记时,在AppVeyor和TravisCI上使用git标志
--depth=1

不应出现问题。相同的哈希用于任何类型的克隆或压缩下载。将构建与存储库匹配没有问题。或者你说的是另一种杂烩?只要您没有在CI系统上执行任何git操作,就不会有问题。从git版本2.25.1开始,很可能更早,浅层克隆的哈希值与完整克隆的哈希值相同。请注意,如果您有滚动生成,克隆深度1通常是可以的,例如,对同一分支的另一次推送会杀死第一个生成。它们配合得很好,因为您总是希望构建head并尽快释放构建代理。这确实意味着,正如您所指出的,重新启动失败的构建可能会出错,但您始终可以从head触发新的构建。
Build started
Fetching repository commit (6ad0f01)...OK
Total: 781.1 KB in 76 files