How do I push all annotated tags from my local repo to the remote, without pushing lightweight tags?
I use lightweight tags locally that I don't want pushed, so git push --tags
is not a solution.
I am aware of git push --follow-tags
but that will only push tags that are associated with commits currently being pushed.
I need this option because my normal workflow involves pushing from time to time, but only tagging when finalizing a release, and I sometimes forget to push a tag. This problem often goes undetected for a long time and causes a bit of confusion with other developers, since we become out of sync with our tags.
Since it's complicated to list which annotated tags exist locally but not remotely, I would like to solve this problem by just pushing all local annotated tags, which will ensure that all developers' local and remote repos have the same annotated tags.
It's not too difficult. First find all annotated tags (by rejecting tags that point directly to commits rather than to annotated tag objects). This is a bit long, so you might wish to write it as a shell function:
list_annotated_tags() {
git for-each-ref --format '%(objecttype) %(refname)' refs/tags |
while read reftype refname; do
case $reftype in tag) echo $refname;; esac
done
}
Read the output of the above and use them as refspec arguments to a git push
command:
git push origin $(list_annotated_tags)
and your script is complete.
I noticed that my lightweight tags don't include a taggerdate
. In that case, this will work at the command line or in a script:
taglist=`git for-each-ref refs/tags --format '%(refname:short) %09 %(taggerdate:short)' | \
grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2}' | \
cut -f 1 | \
tr '\n' ' '`
followed by:
git push origin $taglist
Command summary, for anyone who is interested:
git for-each-ref
tag list, formatted to show the tagname, a tab, and the date. (Only annotated tags will have a date.) grep
command searches through the 1st command's results, pulling only those tags with dates.cut
command removes everything after the initial column (ie, from before the tab following each tagname to the newline
ending each result line).tr
command replaces newline
with a space in the end results. (The tagnames are now on one line, separated with spaces.)The results are stored in a variable (taglist
- note the backticks at the beginning and end of the entire command set following the taglist=
).
Finally, then, you push the tag list to origin (using a $
to indicate that taglist
is a variable).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With