Short Note: auto-tag commits on main branch
In case you use some tools (like goreleaser
) that depend on running in the case of tagged commits only, but you wish at the same time not to bother with manually tagging your commits but just to push to master… I found a nice & easy way to auto-tag commits locally with a “post commit” Git hook.
TL;DR: If you wish to use this approach, here is the post commit hook:
#!/bin/sh
COMMIT=$(git rev-parse --short HEAD)
DATE=$(git log -1 --format=%cd --date=format:"%Y%m%d")
git tag -a "$DATE-$COMMIT" -m "Tagging $DATE-$COMMIT"
echo "Code commited and tagged as $DATE-$COMMIT"
echo "Removing deprecated un-pushed tags..."
git show-ref --tags | \
grep -v -F "$(git ls-remote --tags origin | grep -v '\^{}' | cut -f 2)" | \
grep -v "$(git rev-parse --short HEAD)" | \
awk -F'/' '{print $3}' | \
xargs -I{} bash -c "git tag --delete {}"
Installation of the hook
To install it, you need to save this file as .git/hooks/post-commit
file and make it executable with chmod +x .git/hooks/post-commit
.
What does it actually do:
Step 1 - create tag on each commit
The following part will generate a reasonable tag value, like 20240921-4318a7c
, by combining current date with the short value of the last commit (the one that has just created, and for which the post-commit
hook was triggered).
COMMIT=$(git rev-parse --short HEAD)
DATE=$(git log -1 --format=%cd --date=format:"%Y%m%d")
git tag -a "$DATE-$COMMIT" -m "Tagging $DATE-$COMMIT"
echo "Code commited and tagged as $DATE-$COMMIT"
Step 2 - remove “deprecated” local tags
In case you created locally 3 commits, you most probably want to only tag the last one, right? That’s why we need to list all the tags that are present only locally and to remove all the other tags previosly locally created by this post commit hook
echo "Removing deprecated un-pushed tags..."
git show-ref --tags | \
grep -v -F "$(git ls-remote --tags origin | grep -v '\^{}' | cut -f 2)" | \
grep -v "$(git rev-parse --short HEAD)" | \
awk -F'/' '{print $3}' | \
xargs -I{} bash -c "git tag --delete {}"
What does this part exactly do:
git show-ref --tags
- list all the known tagsgrep -v -F "$(git ls-remote --tags origin | grep -v '\^{}' | cut -f 2)"
- find the tags that are known on theorigin
remote (you might want to replaceorigin
with the name of your remote in case you don’t use the default one), and create a negative regex filter for those for the incoming streamgrep -v "$(git rev-parse --short HEAD)"
- identify the current tag (which we want to keep since we’ve just made it) and create a negative filter to exclude it from the incoming streamawk -F'/' '{print $3}'
- keep only the last part of the tag names only by removing all the text before the last/
characterxargs -I{} bash -c "git tag --delete {}"
- run the tag deletion of the tags that remain
Subscribe to my newsletter
Read articles from Milan Aleksić directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by