对Travis和其他CI服务进行浅层克隆的缺点是什么?

时间:2015-07-07 20:02:24

标签: git continuous-integration travis-ci shallow-clone appveyor

大多数CI服务提供了一种浅层克隆存储库的方法。例如,在特拉维斯:

git:
  depth: 1

或AppVeyor:

clone_depth: 1
or
shallow_clone: true

这具有速度的明显好处,因为您不必克隆整个存储库。

CI服务的浅层克隆是否有任何缺点?是否存在浅层克隆会导致CI构建失败的情况?否则,为什么不浅层克隆这些CI服务的默认设置?

3 个答案:

答案 0 :(得分:9)

有两个原因导致它通常不会发生。

首先,浅层克隆的哈希值将与您在存储库中可能拥有的任何版本不同。因此,无法跟踪您对任何特定结果所做的构建。

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

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

答案 1 :(得分:5)

添加到AlBlue的答案:

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

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

如果我们在子模块中指向的提交不在当前主设备的n次提交中(其中n是深度设置),那么它将无法检出。

答案 2 :(得分:4)

默认行为和选项

Travis CI 上,默认行为是使用50的克隆深度。
TravisCI documentation, git-clone-depth

git:
  depth: 3
# Or remove the --depth flag entirely with:
git:
  depth: false

AppVeyor 上,默认设置是克隆整个存储库。
AppVeyor提供了设置克隆深度和备用shallow_clone: true选项的功能,其中使用GitHub或Bitbucket API以zip存档的形式下载提交。 (AppVeyor documentation。)

reference appveyor.yml中的描述:

# fetch repository as zip archive
shallow_clone: true                 # default is "false"

# set clone depth
clone_depth: 5                      # clone entire repository history if not defined

请勿在项目中为CI使用depth = 1!

在CI平台开始克隆所需的提交之前,将新的提交推入分支时,使用(clone_)depth: 1通常会导致git错误。 无论是在AppVeyor还是TravisCI上,都可以正常推送到GitHub上的存储库。

在AppVeyor上结帐失败的示例输出:

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

请注意,没有特定的提交被拉!

使用AppVeyors替代项shallow_clone: true

Build started
Fetching repository commit (6ad0f01)...OK
Total: 781.1 KB in 76 files

使用shallow_clone: true设置的项目没有出现任何问题。

基于旧提交重新启动

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

建议

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

在TravisCI上,不设置深度(并使用默认深度50)似乎是合理的。 如果您不想触发历史构建或根据存储库中的流量进行优化,则可以使用其他值。

克隆依赖项

外部依赖关系通常由分支或标记引用。 在克隆分支或标签的尖端时,使用git标志--depth=1应该不会有问题。