git tag -a / -d: Usage, Options & Common CI Errors
By Kaveh Alemi·Latchkey
git tag -a creates an annotated release tag; git tag -d removes a tag from your local repo.
Annotated tags carry an author, date, message, and optional signature - the right choice for releases. Deletion is local only; the remote tag needs a separate push to remove.
What it does
git tag -a creates an annotated tag object (stored with tagger, date, and message), unlike a lightweight tag which is just a pointer. git tag -d removes the named tag from the local repository.
Common usage
Terminal
git tag -a v1.2.0 -m "Release 1.2.0"
git tag -a v1.2.0 <sha> -m "Release" # tag a specific commit
git tag -d v1.2.0 # delete locally
git push origin v1.2.0 # publish the tag
git push origin :refs/tags/v1.2.0 # delete on the remote
Options
Flag
What it does
-a / --annotate
Create an annotated tag
-m <msg>
Tag message (implies annotated)
-s / --sign
GPG-sign the tag
-d / --delete
Delete a tag locally
-f / --force
Move an existing tag
Common errors in CI
fatal: tag 'vX' already exists - re-tagging needs -f locally and git push --force origin vX (or delete-then-push) on the remote. Deleting locally with -d does not remove the remote tag; push the :refs/tags/<name> deletion explicitly.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
.github/workflows/ci.yml
- uses:actions/checkout@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
Frequently asked questions
git tag -a / -d: Usage, Options & Common CI Errors?
Annotated tags carry an author, date, message, and optional signature - the right choice for releases. Deletion is local only; the remote tag needs a separate push to remove.
What it does?
git tag -a creates an annotated tag object (stored with tagger, date, and message), unlike a lightweight tag which is just a pointer. git tag -d removes the named tag from the local repository.
Common errors in CI?
fatal: tag 'vX' already exists - re-tagging needs -f locally and git push --force origin vX (or delete-then-push) on the remote. Deleting locally with -d does not remove the remote tag; push the :refs/tags/<name> deletion explicitly.