Disadvantages of shallow cloning on Travis and other CI services?
Asked Answered
S

4

17

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?

Sigismund answered 7/7, 2015 at 20:2 Comment(0)
S
11

There's two reasons why it doesn't usually happen.

Firstly, the hash of a shallow clone is going to be different from any version that you may have in the repository. As a result, it's not going to be possible to track a build that you've done to any particular result.

Secondly most Git servers have the ability to send the optimised 'everything.pack' if you have no details. Otherwise the server will have to provide a custom commit pack which contained just your shallow copy to send to you. So although there may be more data transmitted across the wire, it may actually result in more work on the server.

Finally quite a lot of CI builds will perform some kind of tag operation and upload it to the repository, and you can't practically tag a shallow clone (see point 1).

Seigneury answered 8/7, 2015 at 21:1 Comment(2)
On both AppVeyor and TravisCI the same hashes are used for any type of clone or compressed download. They have no issue matching the builds to the repository. Or are you talking about a different kind of hash? As long as you are not doing any git operations on the CI system there should not be an issue.Spur
As of git version 2.25.1 and likely much earlier too, the hash of shallow clones is the same than for full clones.Uncork
S
7

Default behaviour and options

On Travis CI the default behaviour is to use a clone-depth of 50.
TravisCI documentation, git-clone-depth:

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

On AppVeyor the default is to clone the whole repository.
AppVeyor offers both setting the clone-depth and an alternative shallow_clone: true option, where the commit is downloaded as a zip-archive using the GitHub or Bitbucket API. (AppVeyor documentation.)

The description in the 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

Do not use a depth=1 on your project for CI!

The use of (clone_)depth: 1 often results in a git error when a new commit has been pushed to a branch before the CI platform started cloning the intended commit. Both on AppVeyor and TravisCI, with normal push operations to a repository on GitHub.

Example output of a failed checkout on 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

Notice that no specific commit was pulled!

Using AppVeyors alternative shallow_clone: true:

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

I have not seen any issue with projects using the shallow_clone: true setting.

Restarting builds on old commits

A secondary result when using a limited depth, is that restarting CI builds on old commits will fail when outside this range.

Advice

On AppVeyor I would advice to use shallow_clone: true if the repository is available on GitHub or Bitbucket. Unless you want to do git operations on the code this seems the best option.

On TravisCI not setting the depth (and using the default depth of 50) seems reasonable. You can use a different value if you do not want to trigger historic builds or optimise based on the traffic on the repository.

Cloning dependencies

External dependencies are usually referenced by branch or tag. When acquiring the tip of a branch or tag is cloned there should not be an issue using the git flag --depth=1.

Spur answered 19/12, 2018 at 19:16 Comment(1)
Just a note that clone depth 1 is generally fine if you have rolling builds on i.e. another push to the same branch kills the first build. They work nicely together cos you always want to build head and free up the build agent ASAP. It does mean as you point out that you may get an error restarting a failed build, but you can always trigger a new build from head instead.Gettings
S
5

Adding to AlBlue's answer:

Another problem is that the clone depth setting is also used for git submodule.

In projects that use git submodule, Travis, etc. will clone the submodule repo starting from master, and then check out the specific revision.

If the commit we're pointing to in the submodule isn't within n commits of the current master (where n is the depth setting), then it'll fail to checkout.

Sigismund answered 3/3, 2016 at 16:15 Comment(0)
P
0

A bit late adding to answers, but since the question references "other CI services" I did want to add an important bit.

SonarQube offers some very detailed CI features which reference the git blame information that is not present in a shallow clone. From this link:

A full clone is required for this integration to be able to collect the required blame information (see Known Issues). If a shallow clone is detected, a warning will be logged and no attempt will be made to retrieve blame information.

If your CI system is mostly just "executing tests on the latest build" this isn't relevant. The extra few seconds of building to enable better analytics may possibly be worth it, depending on your CI needs.

Pleach answered 16/8, 2021 at 6:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.