gitcicdgit-fetchgit-ls-remote

Why does `git ls-remote --tags` require `git fetch --tags --prune` to work?


I’m working on optimizing my GitHub Actions pipeline. One of the steps involves retrieving the latest tag from my Git repository.

Initially, I used the following commands to fetch the latest tag:

git fetch --prune --unshallow --tags
TAG=$(git describe --tags --abbrev=0) # Find the latest tag

This worked but git fecth took a lot of time because the repository is quite large, so I decided to optimize it by replacing it with:

git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r | head -1

This worked perfectly on my local machine, but in the CI/CD environment, I encountered this error:

fatal: missing object <object-id> for refs/tags/<tag-name>

The error persisted even after I deleted the problematic tag from the remote repository. However, when I added the following step to fetch and prune the tags before running git ls-remote, the issue disappeared:

git fetch --tags --prune
git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r | head -1
  1. Why does git ls-remote, which is supposed to work independently of the local repository, require a git fetch --tags --prune step to work properly in my CI/CD environment?
  2. Is this related to caching, stale references, or some other aspect of Git’s behavior?
  3. What is the best solution for finding latest tag without fetching all tags?

Environment:


Solution

  • Sorting happens locally, not at the remote side.

    The documentation clearly states:

    [...] but be aware keys like committerdate that require access to the objects themselves will not work for refs whose objects have not yet been fetched from the remote, and will give a missing object error.

    So, obviously it is necessary to fetch the objects first in order to be able to sort by committerdate.