checkout overwrites tags with lightweight tags
When running checkout with fetch-depth: 0 on a tag ref, checkout clobbers the fetched tag by replacing it with its own lightweight tag.
The cause of this is testRef is comparing a tag-object with a commit-object. git rev-parse on a non-lightweight tag ref returns the tag object and not the commit object:
// refs/tags/
else if (upperRef.startsWith('REFS/TAGS/')) {
const tagName = ref.substring('refs/tags/'.length)
return (
(await git.tagExists(tagName)) && commit === (await git.revParse(ref))
)
}
After this test fails, checkout then performs a 2nd fetch of the commit which results in a lightweight tag being created, overwriting the original tag.
This breaks git describe and other things.
Build log:
$ git cat-file -t 64c28bc66b5420d8bfb158088b830fc6cdb02815
tag
$ git cat-file -p 64c28bc66b5420d8bfb158088b830fc6cdb02815
object 4583104281ae74cb64a04aa28615c062752f1d64
type commit
tag R2
tagger James Carroll <[email protected]> 1659879755 +0100
Test
$ git cat-file -t 4583104281ae74cb64a04aa28615c062752f1d64
commit
$ git cat-file -p 4583104281ae74cb64a04aa28615c062752f1d64
tree 0f020f42f0099856c28e138234f6cb22130bde36
parent 483c83b4723c31e32a6722985f16a840742c99b3
author James Carroll <[email protected]> 1659879639 +0100
committer James Carroll <[email protected]> 1659879727 +0100
Test fetch without force
/usr/bin/git -c protocol.version=2 fetch --prune --progress --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*
...
* [new branch] main -> origin/main
* [new tag] R1 -> R1
* [new tag] R2 -> R2
/usr/bin/git tag --list R2
R2
/usr/bin/git rev-parse refs/tags/R2
64c28bc66b5420d8bfb158088b830fc6cdb02815
/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules origin +4583104281ae74cb64a04aa28615c062752f1d64:refs/tags/R2
From https://github.com/MrCarroll/runelite-snap
t [tag update] 4583104281ae74cb64a04aa28615c062752f1d64 -> R2
It's really very unexpected behaviour 🤔 Moreover, this issue initiates other problem with using some tools that depends on type of tags (JGitVer for example).
And for cutting a release I must use workaround and re-fetch all tags manually 😞
- name: Checkout
uses: actions/checkout@v3
with:
# we don't know what commit the last tag was
fetch-depth: 0
- run: git fetch --tags --force origin # WA: https://github.com/actions/checkout/issues/882
not sure if anyone is monitoring this...any and all help appreciated!
I added the work around but if I do a repo.Tags.CountI() I still get zero!
the is what I see in the log:
Run git fetch --tags --force origin
git fetch --tags --force origin
shell: /usr/bin/bash -e {0}
I note when the workflow is retrieve the repo it runs:
/usr/bin/git -c protocol.version=2 fetch --prune --progress --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*
It seem I'm running checkout@2 as that is what Nuke.build is currently using.
We've run into this as well when upgrading our workflows for the Git LFS project. Our proposed workaround at present is to run the following:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch origin "+${GITHUB_REF}:${GITHUB_REF}"
if: ${{ github.ref_type == 'tag' }}
shell: bash
That seems to be enough to reverse the tag update made by mistake which overwrites the annotated tag and turns it into a lightweight one.
For me the annotated tag appears as lightweight even when I checkout without the fetch-depth: 0 restriction. Workarounds suggested above work fine.
A full workday wasted to investigate why Jgitver did not work in GitHub Actions. Then I found this issue. The problem was filed here over a year ago. Why has it not yet been fixed?
Thankfully a workaround exist. I am currently using this in my workflow
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
But this is a hack, and it clutters the workflow.
Related to #290, possibly a duplicate?