= How to work with git tags = **Summary**: On this page I'll explain a few thing regarding git tags and why they are important in modern infrastructure. I'll show you the most used commands, and what to take into account when using git tags for argocd. I'll also share tips and tricks to help you work with git tags more efficiently. \\ **Date**: 9 December 2024 \\ {{tag>git}} == Why are Git Tags Important == I come from an infrastructure background, and I've learned some git along the way just to check in my scripts and infra as code. However, when working with kubernetes and deploying applications using gitops (argocd) I came across git tags. Git tags allow you to put a label on a commit, and you can use that label in your argocd application. If you do that, argocd will only look at that label. And if you would change the commit that label is pointing to, argocd will see that and deploy the new commit. This is a very powerful feature, and allows you to deploy new releases with argocd without having to change anything in argocd. You just have to change the tag in your git repo, but to do that properly, especially for argocd, you need to know how git tags work. == Git Tag Basics == There are two types of tags in git: * lightweight: A lightweight tag is just a pointer to a commit * annotated: An annotated tag is stored as a full object in the git database. It has a tagger name, email, date, and a tagging message. Learn yourself to only use annotated tags. They are more powerful and give you more information. == Lightweight Tags == We'll not spends much time on lightweight tags, but here are the commands to create and delete them: # Create a tag without annotation git tag v1.0 # Delete a tag git tag -d v1.0 == Annotated Tags == Annotated tags are more useful as they provide you with more information, and they are actually objects in the git database. Make yourself familiar with them: # Create a tag with annotation git tag -a v1.0 -m "Release 1.0" # To list all tags git tag # To list all tags with their annotations git tag -n # Sometimes tag messages are (very) long so you want to limit the output git tag -n1 # To show the first line of the annotation git tag -n10 # To show the first 10 characters of the annotation == Seeing it in Practice == Let's check how a tag shows up in your command prompt: # Let's start with a lightweight tag PS C:\Repos\GetShifting\knowledge> git tag v1.0 PS C:\Repos\GetShifting\knowledge> git tag --list v1.0 PS C:\Repos\GetShifting\knowledge> git tag --list -n1 v1.0 dokuwiki - working on old pages # Hang on here, did you see that? The annotation is the commit message. # So that might set you off, but how can we check if this is an annotated tag or not? # We can do that by using the cat-file command PS C:\Repos\GetShifting\knowledge> git cat-file -p v1.0 tree 9b7d6790ab2706d8d50ad21dd4d6a1d831886019 parent 269ccbc73cee6f40943accbdcc628bf43b487b09 author Sjoerd Hooft 1733671308 +0100 committer Sjoerd Hooft 1733671308 +0100 dokuwiki - working on old pages # Or by using the show command (I'll use the --name-only option to show only the changed files and leave out all the actual changes) PS C:\Repos\GetShifting\knowledge> git show v1.0 --name-only commit a3cc61f54b33ae8a7dccf69cbc5949f8666cd275 (HEAD -> main, tag: v1.0, origin/main, origin/HEAD) Author: Sjoerd Hooft Date: Sun Dec 8 16:21:48 2024 +0100 dokuwiki - working on old pages README.md dokuwiki/pages/adcontrols.txt # As you can see, the output just shows the commit message, and it shows the tag in the show command but it doesn't really show the tag. Because it's a lightweight tag. # Let's create an annotated tag and see how that looks PS C:\Repos\GetShifting\knowledge> git tag -a v1.1 -m "Release 1.1" PS C:\Repos\GetShifting\knowledge> git tag --list v1.0 v1.1 PS C:\Repos\GetShifting\knowledge> git tag --list -n1 v1.0 dokuwiki - working on old pages v1.1 Release 1.1 # Now let's see into the tag to check the difference PS C:\Repos\GetShifting\knowledge> git cat-file -p v1.1 object cbc7d216b1ee94ba2a412b3b3575c1a2d2ea1623 type commit tag v1.1 tagger Sjoerd Hooft 1733775120 +0100 Release 1.1 PS C:\Repos\GetShifting\knowledge> git show v1.1 --name-only tag v1.1 Tagger: Sjoerd Hooft Date: Mon Dec 9 21:12:00 2024 +0100 Release 1.1 commit cbc7d216b1ee94ba2a412b3b3575c1a2d2ea1623 (HEAD -> main, tag: v1.1) Author: Sjoerd Hooft Date: Mon Dec 9 21:05:25 2024 +0100 dokuwiki - gittag - making progress drafts/shift-gittag.txt # Now both outputs are clearly different from before. The cat-file command shows the tag and the tagger instead of the committer, and the git show command shows first the tag information, and then the commit information. Use the git show command to see the full annotation of a tag. == Setting a tag on a specific commit == Sometimes you want to set a tag on a specific commit. You can do that by using the commit hash: # First get the commit hash PS C:\Repos\GetShifting\knowledge> git log --oneline -4 cbc7d21 (HEAD -> main, tag: v1.1) dokuwiki - gittag - making progress a3cc61f (tag: v1.0, origin/main, origin/HEAD) dokuwiki - working on old pages 269ccbc dokuwiki - all cheatsheets 924e132 dokuwiki - azurekusto and chaetsheet changes # Now set the tag PS C:\Repos\GetShifting\knowledge> git tag -a cheatsheets 269ccbc -m "This is my tag for the cheatsheets" PS C:\Repos\GetShifting\knowledge> git tag -l -n1 cheatsheets This is my tag for the cheatsheets v1.0 dokuwiki - working on old pages v1.1 Release 1.1 == Pushing and Deleting Tags == It's possible to delete tags as well. And you can push them to the remote. And you can delete them on the remote as well, but before you start re-using tags (e.g. re-tagging) you should read [[https://git-scm.com/docs/git-tag#_on_re_tagging|this article]], as once people have pulled your tags, they will have to do some extra work to get the new tags. # To push a tag to the remote git push origin v1.0 # To push all tags to the remote git push origin --tags # To delete a tag git tag -d v1.0 # To delete a tag on the remote git push origin --delete v1.0 === So how does that work with ArgoCd === At the start of this page I told about argocd and how it just looks at the tag. But re-tagging is a bit of a problem. If you re-tag a commit, argocd will see that as a new commit and will deploy that. So if you want to re-tag a commit, you should delete the old tag first, and then push the new tag. But this tag does not automatically update at the local repository of other developers. So how can this go well? \\ Well, it's simple. Use dedicated tags for argocd, that are maintained on the remote only. For example: # Create a tag with annotation git tag -a argocd-app1 -m "Release 1.0" # Push the tag to the remote git push origin argocd-app1 # Now, if argocd is set up to use this tag, it will deploy this commit # If you have made updates and want to deploy them, you can just re-tag the commit by using --force git tag -a argocd-app1 -m "Release 1.1" --force # Push the tag to the remote git push origin argocd-app1 --force And this can also be done on an older commit: git tag -a -f argocd-app1 15027957951b64cf874c3557a0f3547bd83b3ff6 Use dedicated tags for argocd, that are maintained on the remote only. === Pulling tags in VSCode === When working with VSCode be aware that the git extension in VSCode has an option to replace tags on pull. That way your local tags are always overwritten by the remote tags. Personally I don't enable this option as I want to know when my local tags are replaced, but if that is no concern to you, you can enable this option: \\ [{{gittag01.png|Replace local tags on pull}}] \\ == Use tags to checkout a branch == You can use tags to checkout a branch. However, you will be in a detached HEAD state. If you want to make changes and keep them, it's recommended to create a new branch. git checkout -b == Some Tips and Tricks == === Git Log 'a dog' === Git log has many options. Just to remind you, you can use the 'a dog' reminder for the following options: git log --all --decorate --oneline --graph * cbc7d21 (HEAD -> main, tag: v1.1) dokuwiki - gittag - making progress * a3cc61f (tag: v1.0, origin/main, origin/HEAD) dokuwiki - working on old pages * 269ccbc (tag: cheatsheets) dokuwiki - all cheatsheets * 924e132 dokuwiki - azurekusto and chaetsheet changes * 92dee03 dokuwiki - cheatsheets + redirects * 3de0fdf readme * 98b2906 dokuwiki - sjoerdhooft * bab3220 dokuwiki - testing with changes and new pages * 7e4fc35 readme + buildthissite * 28c8333 pipeline - changes file pattern for media files As you can see, this shows you the hashes, commits, tags, and branches in a nice overview. === See all the commits leading up to a tag === git log --decorate --oneline -10 v1.0 === See all tags and the full commit hash === git show-ref --tags === See the tagger and the date of the tag for all tags === PS C:\Repos\GetShifting\knowledge> git for-each-ref --format '%(refname) %09 %(taggerdate) %(subject) %(taggeremail)' refs/tags --sort=taggerdate refs/tags/v1.0 dokuwiki - working on old pages refs/tags/v1.1 Mon Dec 9 21:12:00 2024 +0100 Release 1.1 refs/tags/cheatsheets Mon Dec 9 21:28:01 2024 +0100 This is my tag for the cheatsheets === See the tagger and the date of the tag for just one tag === PS C:\Repos\GetShifting\knowledge> git for-each-ref --format '%(refname) %09 %(taggerdate) %(subject) %(taggeremail)' refs/tags/cheatsheets --sort=taggerdate refs/tags/cheatsheets Mon Dec 9 21:28:01 2024 +0100 This is my tag for the cheatsheets === Git log with relative dates === PS C:\Repos\GetShifting\knowledge> git log --pretty=format:"%h %s %an %ar %C(auto)%d" cheatsheets 269ccbc dokuwiki - all cheatsheets Sjoerd Hooft 31 hours ago (tag: cheatsheets) 924e132 dokuwiki - azurekusto and chaetsheet changes Sjoerd Hooft 31 hours ago 92dee03 dokuwiki - cheatsheets + redirects Sjoerd Hooft 34 hours ago 3de0fdf readme Sjoerd Hooft 2 days ago === Git log with the date after the hash in blue === PS C:\Repos\GetShifting\knowledge> git log --pretty=format:'%C(auto)%h%C(blue) %<|(19)%as%C(auto)%d %s' cheatsheets 269ccbc 2024-12-08 (tag: cheatsheets) dokuwiki - all cheatsheets 924e132 2024-12-08 dokuwiki - azurekusto and chaetsheet changes 92dee03 2024-12-08 dokuwiki - cheatsheets + redirects 3de0fdf 2024-12-07 readme 98b2906 2024-12-07 dokuwiki - sjoerdhooft === Git log with the date after the hash in blue and the author in red === PS C:\Repos\GetShifting\knowledge> git log --pretty=format:'%C(auto)%h%C(blue) %<|(19)%as%C(auto)%d %s %C(red)%an' cheatsheets 269ccbc 2024-12-08 (tag: cheatsheets) dokuwiki - all cheatsheets Sjoerd Hooft 924e132 2024-12-08 dokuwiki - azurekusto and chaetsheet changes Sjoerd Hooft 92dee03 2024-12-08 dokuwiki - cheatsheets + redirects Sjoerd Hooft 3de0fdf 2024-12-07 readme Sjoerd Hooft 98b2906 2024-12-07 dokuwiki - sjoerdhooft Sjoerd Hooft === See a lot of information about a tag in one copy paste === # Set the tag $tag = "cheatsheets" # See who and when the tag was set (1 line) git for-each-ref --format '%(refname) %09 %(taggerdate) %(subject) %(taggeremail)' refs/tags/$tag --sort=taggerdate # See the last 10 commits leading to the commit where a tag is set - easy overview git log --decorate --oneline -10 $tag # Include the relative date git log --pretty=format:'%C(auto)%h%C(blue) %<|(19)%ar%C(auto)%d %s %C(red)%an' -10 $tag # Include the full date git log --pretty=format:'%C(auto)%h%C(blue) %<|(19)%ad%C(auto)%d %s %C(red)%an' -10 $tag # Show tag (tagger, commit) with only changed file names git show --name-only $tag === Bonus: See the changes in a previous commit === git show --name-only == Useful Links == * [[https://git-scm.com/book/en/v2/Git-Basics-Tagging|Git Basics - Tagging]] * [[https://git-scm.com/docs/pretty-formats/2.26.0|Git Pretty Formats]]