简体   繁体   中英

Get latest tag `git describe --tags' when repo is cloned with depth=1

I have an issue reading the tags of a git repository during the CI automated workflow. I do not want to create a full-clone as this incurs extensive overhead so would prefer to maintain a 'shallow clone' but somehow determine the tag for application versioning.

Use Case

  1. Github Actions CI build checks out the Git-Repository as a 'shallow' clone by setting git clone... --depth=1 .
  2. The pre-build stage performs git describe --tags to embed version-information into the compiled application

Expected outcome

With full-clone the tag would be reported as follows:

> git describe --tags
v0.5.0-95-g7bbc323

Actual outcome

The shallow-clone under CI does not work the same:

> git describe --tags
fatal: No names found, cannot describe anything.

Solution Ideas

  • Modify the 'clone' under the CI to include tags somehow?
  • Modify the pre-build 'desribe' step to read the tags from the remote if this were possible?

You cannot do this. In order to have git describe work, you have to have the tags and the commits to which they point, and be able to walk backwards through history, finding the nearest tag in history. When you've cloned with --depth=1 , you've cloned only a single commit, so traversal is not possible.

However, you could do a partial clone with --filter=tree:0 and then you'd have only tags and commits until you did a checkout, when the blobs and trees for only that commit would be filled in from the server. However, I'm not sure if GitHub Actions supports this natively, so you may have to do it yourself.

You could also look up on the remote, and get the latest tag from there. Then when you have it, you can fetch only that one.

tag=$(git ls-remote origin "refs/tags/v*[0-9]" | cut -f 2- | sort -V | tail -1)
git fetch --depth 1 origin "$tag":"$tag"

The above script should only fetch the latest tag (given that you start them with v and ends with a number.

Buuut. Sadly it doesn't fix the git describe problem, since you're missing all the commits between this tag (which you have all data for) and the shallow commit that's your main .

So I just YOLO'd it with git clone --depth 1024 now, surely we should tag much more often than that.

You can do this fairly easily, getting a sliced-up history like this just requires knowing where to step, so to speak:

For a hosting server that supports filtering (all the big ones do):

git fetch --filter=tree:0 origin +refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/*

Otherwise, cd in to the upstream repo yourself, and

git bundle create just-the-structure.bundle --filter=tree:0 --tags --branches

then copy that file to your destination system, and in your target repo

git bundle unbundle just-the-structure.bundle

For me I just did the following:

      - name: Get latest tag
    run: |
      git fetch -a
      latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)

Hope this helps: :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM