# Fix Git Shallow Clone Missing Tags Causing Build Failures
You clone a repository with --depth 1 for faster CI builds:
git clone --depth 1 https://github.com/user/repo.gitBut your build script fails because it cannot find git tags:
git describe --tags
# fatal: No tags can describe 'abc1234'Or:
git tag -l "v*"
# (empty - no tags found)Shallow clones do not include tags by default, which breaks version detection, semantic release, and build scripts that rely on tag information.
Understanding Shallow Clone Limitations
A shallow clone (--depth 1) only downloads the most recent commit. It does not include:
- Full commit history
- Tags (unless explicitly fetched)
- Branches other than the one you cloned
This makes it fast but incomplete. Many build tools assume a full clone.
Step 1: Fetch Tags After Cloning
If you already have a shallow clone, fetch the tags:
git fetch --depth=1 origin "+refs/tags/*:refs/tags/*"Or fetch all tags:
git fetch --tagsThe --tags flag fetches all tags from the remote, even if they are not on the cloned branch.
Step 2: Clone With Tags
For a fresh clone that includes tags:
git clone --depth 1 --no-single-branch https://github.com/user/repo.gitThe --no-single-branch flag fetches all branch references, which includes tags pointing to those branches. However, tags pointing to commits not on any fetched branch will still be missing.
Step 3: The Correct Approach for CI
For CI builds that need both speed and tag information:
# Shallow clone with tag fetching
git clone --depth 50 https://github.com/user/repo.git
cd repo
git fetch --tagsUsing --depth 50 instead of --depth 1 provides enough history for git describe to work for recent tags. The git fetch --tags ensures all tags are available.
Step 4: GitHub Actions Specific Fix
In GitHub Actions, the default actions/checkout performs a shallow clone:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full clone (slow but complete)Or for a shallow clone with tags:
- uses: actions/checkout@v4
with:
fetch-depth: 50
fetch-tags: trueThe fetch-tags: true option (available in v4+) fetches tags even with shallow clones.
Step 5: GitLab CI Specific Fix
In GitLab CI, the default behavior depends on the GIT_STRATEGY variable:
```yaml variables: GIT_STRATEGY: clone GIT_DEPTH: 50
script: - git fetch --tags - git describe --tags ```
Set GIT_DEPTH to control shallow clone depth and explicitly fetch tags.
Step 6: Semantic Release and git-describe
Tools like semantic-release and git describe need tag history to determine the current version:
git describe --tags --always --dirty
# v2.3.1-15-gabc1234This shows: tag v2.3.1, 15 commits after the tag, at commit abc1234.
For this to work, the commit being described must be reachable from a tag in the clone. With --depth 1, if the current commit IS the tagged commit, it works. If the current commit is 20 commits after the latest tag, you need at least --depth 20.
Step 7: Determining the Right Depth
Calculate the minimum depth needed:
# On a full clone, find the distance to the nearest tag
git describe --tags --long
# v2.3.1-15-gabc1234
# Need at least depth 15Set your shallow clone depth to this number plus a buffer:
git clone --depth 30 https://github.com/user/repo.gitStep 8: Unshallow an Existing Clone
If you have a shallow clone and need full history:
git fetch --unshallowThis converts the shallow clone to a full clone by downloading all missing history. This can take significant time and bandwidth for large repositories.
For partial unshallowing (only up to a specific tag):
git fetch --depth=100This extends the history to 100 commits, which may be enough for your build needs without downloading the entire history.