2

I run a private repository which uses lightweight tags, as it allows for easy testing and review before going public.

One of our tags was created with an incorrect name (v0.21. vs v0.2.1). Additionally, this tag was created as an annotated tag on accident. As such, editing the tag would modify its creation date, making our GitHub releases display in a non-chronological order.

I know it's possible to convert a lightweight tag to an annotated tag. Is it possible to do the reverse and downgrade an annotated tag to a lightweight tag?

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
  • 1
    A normal tag doesn't have it's own date, it "uses" the date of the commit it points to. It's just a label (like a branch) to a commit. – MrTux Apr 18 '17 at 16:06
  • @MrTux That's only true for lightweight tags. [Annotated tags are unique objects with their own message, author, and creation date](http://stackoverflow.com/a/25996877/3357935). – Stevoisiak Apr 18 '17 at 16:09
  • 3
    The question was how to replace an annotated tag with a lightweight tag - thus my comment is true. Just delete it and create a new normal tag. – MrTux Apr 18 '17 at 16:10

1 Answers1

0

Here's what I did, based on MrTux's comment:

List all the tags and their associated commits

git for-each-ref --sort -v:refname --format '%(objectname) %(objecttype) %(refname)
%(*objectname) %(*objecttype) %(*refname)' refs/tags
  • If an entry looks like this, then it's an annotated tag:

    f844099a21d37a0139cbccd1f179113937d3fe69 tag refs/tags/v0.4.1
    1639e13f12fac2c36b7d50661589990355c03419 commit refs/tags/v0.4.1^{}
    
  • If an entry looks like this, then it's a lightweight tag since there's no tag hash:

    644adce83cdd25057fa865701c509d852d5d44d5 commit refs/tags/v0.4.0
    refs/tags/v0.4.0^{}
    

To replace one annotated tag with a lightweight tag

(Using the example from above)

  1. Delete the tag, e.g.

    git tag -d v0.4.1
    
  2. Create a new tag

    git tag v0.4.1 1639e13f12fac2c36b7d50661589990355c03419
    
    • Make sure to use the commit hash of the original tag and not the tag hash
    • Make sure not to use -a, -s, or -u as these will create annotated tags

To replace all annotated tags with lightweight tags

git for-each-ref --format="%(refname:short) %(*objectname)" "refs/tags/*" | while IFS= read -r line; do tag=$(echo "$line" | cut -f 1 -d " "); hash=$(echo "$line" | cut -f 2 -d " "); git tag -d $tag && git tag $tag $hash; done
bmaupin
  • 14,427
  • 5
  • 89
  • 94