14

Most CI services provide a way to shallow clone a repository. For example, on Travis:

git:
  depth: 1

or on AppVeyor:

clone_depth: 1
or
shallow_clone: true

This has the obvious benefit of speed, since you don't have to clone the whole repository.

Is there any disadvantages to shallow cloning on CI services? Is there any situation where a shallow clone would make a CI build fail? Otherwise, why isn't shallow cloning the default setting for these CI services?

4

4 回答 4

11

通常不会发生的原因有两个。

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

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

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

于 2015-07-08T21:01:56.753 回答
7

默认行为和选项

Travis CI上,默认行为是使用 50 的克隆深度。
TravisCI 文档 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 文档。)

参考 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!

(clone_)depth: 1在 CI 平台开始克隆预期的提交之前,当新的提交被推送到分支时,使用通常会导致 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 构建将在超出此范围时失败。

建议

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

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

克隆依赖项

外部依赖通常由分支或标签引用。当获取分支或标签的尖端被克隆时,使用 git 标志不应该有问题--depth=1

于 2018-12-19T19:16:43.237 回答
5

添加到 AlBlue 的答案:

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

在使用 git submodule 的项目中,Travis 等会从 master 开始克隆子模块 repo,然后查看具体的修订版本。

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

于 2016-03-03T16:15:24.313 回答
0

添加答案有点晚,但由于问题引用了“其他 CI 服务”,我确实想添加一个重要的内容。

SonarQube 提供了一些非常详细的 CI 功能,这些功能引用git blame了浅层克隆中不存在的信息。从这个链接

此集成需要完整克隆才能收集所需的责备信息(请参阅已知问题)。如果检测到浅克隆,将记录警告并且不会尝试检索责备信息。

如果您的 CI 系统主要只是“在最新版本上执行测试”,那么这无关紧要。根据您的 CI 需求,额外几秒钟的构建以实现更好的分析可能是值得的。

于 2021-08-16T06:30:04.843 回答