wiki.getshifting.com

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


gittag

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

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 <sjoerd@getshifting.com> 1733671308 +0100
committer Sjoerd Hooft <sjoerd@getshifting.com> 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 <sjoerd@getshifting.com>
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 <sjoerd@getshifting.com> 1733775120 +0100
 
Release 1.1
PS C:\Repos\GetShifting\knowledge> git show v1.1 --name-only
tag v1.1
Tagger: Sjoerd Hooft <sjoerd@getshifting.com>
Date:   Mon Dec 9 21:12:00 2024 +0100
 
Release 1.1
 
commit cbc7d216b1ee94ba2a412b3b3575c1a2d2ea1623 (HEAD -> main, tag: v1.1)
Author: Sjoerd Hooft <sjoerd@getshifting.com>
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 <tag> 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 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:

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 <new-branch-name> <tagname>

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 <tag>
* 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 <sjoerd@getshifting.com>
refs/tags/cheatsheets    Mon Dec 9 21:28:01 2024 +0100 This is my tag for the cheatsheets <sjoerd@getshifting.com>

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 <sjoerd@getshifting.com>

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 <hash>
gittag.txt · Last modified: by 127.0.0.1