You can try, with git1.8.3+ (May 2013):
git push --follow-tags
The new "--follow-tags" option tells "git push" to push relevant annotated tags when pushing branches out.
This won't push all the tags, but only the ones accessible from the branch(es) HEAD(s) you are pushing.
As mentioned in "Push a tag to a remote repository using Git?", this concerns only annotated tags, not lightweight tags.
git tag 1.0 (lightweight) would not be pushed with --follow-tags, it would with git push --tags.
With Git 2.4.1+ (Q2 2015), that option can be set as default.
See commit a8bc269 by Dave Olszewski (cxreg):
make it easier to add new configuration bits and then add push.followTags configuration that turns --follow-tags option on by default.
The documentation will include:
push.followTags::
If set to true enable '--follow-tags' option by default. You may override this configuration at time of push by specifying '--no-follow-tags'
Do enable this setting globally, you can run git config --global push.followTags true. It can also be specified on a per repository-basis.
I need a solution that can also push lightweight tags.
These limitations between lightweight and annotated tags are so annoying in Git.
Pushing lightweight tags alongside annotated tags is a more complex scenario: Lightweight tags are simpler pointers to specific commits, without the additional metadata or checksum verification provided by annotated tags. Git's built-in options for pushing tags (--tags and --follow-tags) differentiate between these types, with --follow-tags designed specifically to push only annotated tags that are reachable from the branches being pushed.
If you need to push both lightweight and annotated tags that are relevant to the branches being pushed, a custom approach is necessary.
First, identify the commits that are part of the branch you are about to push. That can be done using git log or git rev-list.
With the list of commits in hand, you can identify both annotated and lightweight tags that point to these commits. That requires filtering the tags based on whether their referenced commit SHA is in the list of branch commits. Once you have identified all relevant tags, you can push the branch and these tags in a single or consecutive Git commands.
For instance, assuming that you are pushing the current branch and identifies tags pointing to any commit in this branch:
# Get the current branch name
current_branch=$(git rev-parse --abbrev-ref HEAD)
# Get all commits on this branch
commits=$(git rev-list $current_branch)
# Initialize an empty string to hold tags to push
tags_to_push=""
# Loop through all tags
for tag in $(git tag); do
# Check if the tag points to a commit on this branch
if echo "$commits" | grep -q $(git rev-parse $tag); then
# If so, add the tag to the list of tags to push
tags_to_push="$tags_to_push $tag"
fi
done
# Push the current branch
git push origin $current_branch
# Push all identified tags
if [ -n "$tags_to_push" ]; then
git push origin $tags_to_push
fi
Or you could use that script to push only lightweight tags, since annotated tags are easy to push with normal git commands:
# Loop through all tags, filtering for those pointing directly to commits (lightweight tags)
for tag in $(git for-each-ref --format '%(refname:short) %(objecttype)' refs/tags | grep ' commit$' | cut -d " " -f1); do
# Check if the tag points to a commit on this branch
if echo "$commits" | grep -q $(git rev-parse $tag); then
# If so, add the tag to the list of tags to push
tags_to_push="$tags_to_push $tag"
fi
done