How to delete a remote tag?

GitGit Tag

Git Problem Overview

How do you delete a Git tag that has already been pushed?

Git Solutions

Solution 1 - Git

You can push an 'empty' reference to the remote tag name:

git push origin :tagname

Or, more expressively, use the --delete option (or -d if your git version is older than 1.8.0):

git push --delete origin tagname

Note that git has tag namespace and branch namespace so you may use the same name for a branch and for a tag. If you want to make sure that you cannot accidentally remove the branch instead of the tag, you can specify full ref which will never delete a branch:

git push origin :refs/tags/tagname

If you also need to delete the local tag, use:

git tag --delete tagname


Pushing a branch, tag, or other ref to a remote repository involves specifying "which repo, what source, what destination?"

git push remote-repo source-ref:destination-ref

A real world example where you push your master branch to the origin's master branch is:

git push origin refs/heads/master:refs/heads/master

Which because of default paths, can be shortened to:

git push origin master:master

Tags work the same way:

git push origin refs/tags/release-1.0:refs/tags/release-1.0

Which can also be shortened to:

git push origin release-1.0:release-1.0

By omitting the source ref (the part before the colon), you push 'nothing' to the destination, deleting the ref on the remote end.

Solution 2 - Git

A more straightforward way is

git push --delete origin YOUR_TAG_NAME

IMO prefixing colon syntax is a little bit odd in this situation

Solution 3 - Git

If you have a remote tag v0.1.0 to delete, and your remote is origin, then simply:

git push origin :refs/tags/v0.1.0

If you also need to delete the tag locally:

git tag -d v0.1.0

See Adam Franco's answer for an explanation of Git's unusual : syntax for deletion.

Solution 4 - Git

Delete all local tags and get the list of remote tags:

git tag -l | xargs git tag -d
git fetch

Remove all remote tags

git tag -l | xargs -n 1 git push --delete origin

Clean up local tags

git tag -l | xargs git tag -d

Solution 5 - Git

git tag -d your_tag_name
git push origin :refs/tags/your_tag_name

The first line deletes your_tag_name from local repo and second line deletes your_tag_name from remote repo.

For those who use GitHub, one more step is needed: discarding draft. enter image description here

Solution 6 - Git

From your terminal, do this:

git fetch
git tag
git tag -d {tag-name}
git push origin :refs/tags/{tag-name}

Now go to and refresh, they disappear.

Solution 7 - Git

git push --delete origin $TAGNAME is the correct approach (in addition of a local delete).

But: make sure to use Git 2.31.

"git push $there --delete"(man) should have been diagnosed as an error, but instead turned into a matching push, which has been corrected with Git 2.31 (Q1 2021).

See commit 20e4164 (23 Feb 2021) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 1400458, 25 Feb 2021)

> ## push: do not turn --delete '' into a matching push
> Noticed-by: Tilman Vogel

> When we added a syntax sugar "git push remote --delete"(man) <ref> to "git push"(man) as a synonym to the canonical git push remote(man) : syntax at f517f1f ("builtin-push: add(man) --delete as syntactic sugar for :foo", 2009-12-30, Git v1.7.0-rc0 -- merge), we weren't careful enough to make sure that <ref> is not empty.
> > Blindly rewriting "--delete " to ":" means that an empty string <ref> results in refspec ":", which is the syntax to ask for "matching" push that does not delete anything.
> > Worse yet, if there were matching refs that can be fast-forwarded, they would have been published prematurely, even if the user feels that they are not ready yet to be pushed out, which would be a real disaster.

Solution 8 - Git

To remove the tag from the remote repository:

git push --delete origin TAGNAME

You may also want to delete the tag locally:

git tag -d TAGNAME

Solution 9 - Git

Delete local tag '12345'
git tag -d 12345
Delete remote tag '12345' (eg; GitHub version too)
git push origin :refs/tags/12345
alternative approach
git push --delete origin tagName
git tag -d tagName

enter image description here

Solution 10 - Git

Just notice that, if you have a remote branch named as a remote tag, these commands are ambiguous:

git push origin :tagname
git push --delete origin tagname

So you must use this command to delete the tag:

git push origin :refs/tags/<tag>

and this one to delete the branch:

git push origin :refs/heads/<branch>

If not, you would get an error like this:

error: dst refspec <tagname> matches more than one.
error: failed to push some refs to '<repo>'

Solution 11 - Git

This two steps works fine:

# delete local tag '1.0.0'
git tag -d 1.0.0

# delete remote tag '1.0.0' (eg, GitHub version too)
git push origin :refs/tags/1.0.0

Solution 12 - Git

Up to 100x faster method for thousands of remote tags

After reading through these answers while needing to delete over 11,000 tags, I learned these methods relying or xargs take far too long, unless you have hours to burn.

Struggling, I found two much faster ways. For both, start with git tag or git ls-remote --tags to make a list of tags you want to delete on the remote. In the examples below you can omit or replace sorting_proccessing_etc with any greping, sorting, tailing or heading you want (e.g. grep -P "my_regex" | sort | head -n -200 etc) :

###This first method is by far the fastest, maybe 20 to 100 times faster than using xargs, and works with a least several thousand tags at a time.###

git push origin $(< git tag | sorting_processing_etc \
| sed -e 's/^/:/' | paste -sd " ") #note exclude "<" for zsh

How does this work? The normal, line-separated list of tags is converted to a single line of space-separated tags, each prepended with : so . . .

tag1   becomes
tag2   ======>  :tag1 :tag2 :tag3

Using git push with this format tag pushes nothing into each remote ref, erasing it (the normal format for pushing this way is local_ref_path:remote_ref_path).

###Method two is broken out as a separate answer elsewhere on this same page

After both of these methods, you'll probably want to delete your local tags too. This is much faster so we can go back to using xargs and git tag -d, which is sufficient.

git tag | sorting_processing_etc | xargs -L 1 git tag -d

OR similar to the remote delete:

git tag -d $(< git tag | sorting_processing_etc | paste -sd " ")

Solution 13 - Git

If you have created a tag called release01 in a Git repository you would remove it from your repository by doing the following:

git tag -d release01 
git push origin :refs/tags/release01 

To remove one from a Mercurial repository:

hg tag --remove featurefoo

Please reference

Solution 14 - Git

If you use SourceTree - a great Git GUI - then you can easily do this without the command line by doing the following:

  1. Open your repository in SourceTree
  2. Select and expand the "Tags" tab on the left
  3. Right-Click on the tag you want deleted
  4. Select "Delete YOUR_TAG_NAME"
  5. In the verification window, select "Remove Tag From Remotes"

YOUR_TAG_NAME will now be removed from your local repository and all remotes - be it GitHub, BitBucket, or wherever else you listed as a remote for that repository.

Also, if you deleted a tag locally but not on the remote origins, and you want to delete it everywhere, then just create a new tag that has the same name and is attached at the same commit as the origins. Then, repeat the steps above to delete everywhere.

Solution 15 - Git

As @CubanX suggested, I've split this answer from my original:

Here is a method which is several times faster than xargs and may scale much more with tweaking. It uses the Github API, a personal access token, and leverages the utility parallel.

git tag | sorting_processing_etc | parallel --jobs 2 curl -i -X DELETE \{} -H 
\"authorization: token GIT_OAUTH_OR_PERSONAL_KEY_HERE\"  \
-H \"cache-control: no-cache\"`

parallel has many operating modes, but generally parallelizes any command you give it while allowing you to set limits on the number of processes. You can alter the --jobs 2 parameter to allow faster operation, but I had problems with Github's rate limits, which are currently 5000/hr, but also seems to have an undocumented short-term limit as well.

After this, you'll probably want to delete your local tags too. This is much faster so we can go back to using xargs and git tag -d, which is sufficient.

git tag | sorting_processing_etc | xargs -L 1 git tag -d

Solution 16 - Git

I wanted to remove all tags except for those that match a pattern so that I could delete all but the last couple of months of production tags, here's what I used to great success:

Delete All Remote Tags & Exclude Expression From Delete

git tag -l | grep -P '^(?!Production-2017-0[89])' | xargs -n 1 git push --delete origin

Delete All Local Tags & Exclude Expression From Delete

git tag -l | grep -P '^(?!Production-2017-0[89])' | xargs git tag -d

Solution 17 - Git

If you're using PowerShell, and you want to delete a bunch of them:

# Local tags:
git tag -l | foreach { git tag -d $_ }

# Remote tags:
git tag -l | foreach { git push --delete origin $_ }

Of course, you can also filter them before deleting:

git tag -l | Where-Object { $_ -like "build-*" } | foreach { git tag -d $_ }

Solution 18 - Git

The other answers point out how to accomplish this, but you should keep in mind the consequences since this is a remote repository.

The git tag man page, in the On Retagging section, has a good explanation of how to courteously inform the remote repo's other users of the change. They even give a handy announcement template for communicating how others should get your changes.

Solution 19 - Git

Simple script to remove given tag from both local and origin locations. With a check if tag really exists.

if [ $(git tag -l "$1") ]; then
    git tag --delete  $1
    git push --delete origin $1

    echo done.
    echo tag named "$1" was not found

How to use:

  • Create shell script file (e.g. and paste content.
  • chmod your script file to make it executable.
  • Make the script globally available
  • cd to your git project
  • Call script (e.g.
    $> tag_name

Solution 20 - Git

For tortoise git users, at a scale of hundreds tags, you can delete multiple tags at once using UI, but the UI is well hidden under context menu.

From explorer windows right click -> Browse references -> Right click on ref/refmotes/name -> choose 'Delete remote tags'

enter image description here


Solution 21 - Git

Seems like a lot of work for something xargs already does. Looking back through this thread, I'm guessing the slowness with xargs that you experienced is because the original answer used xargs -n 1 when it didn't really need to.

This is equivalent to your method one except that xargs automatically deals with the maximum command line length:

git tag | sorting_processing_etc | xargs git push --delete origin

xargs can run processes in parallel too. Method 2 with xargs:

git tag | sorting_processing_etc | xargs -P 5 -n 100 git push --delete origin

The above uses a maximum of 5 processes to handle a maximum of 100 arguments in each process. You can experiment with the arguments to find what works best for your needs.

Solution 22 - Git

If you have a tag created starting with the # character, e.g. #ST002, you might find that u are unable to delete using normal patterns. i.e.

git tag -d #STOO2

Will not delete the tag, but wrapping it in a String Literal like so

git tag -d "#ST002" or git tag -d '#ST002'

That will get it deleted. Hoping it will help someone who made the mistake of using # to write tag names.

Solution 23 - Git

Just wanted to share an alias I created which does the same thing:

Add the following to your ~/.gitconfig

	delete-tag = "!f() { \
			echo 'deleting tag' $1 'from remote/origin ausing command: git push --delete origin tagName;'; \
			git push --delete origin $1; \
			echo 'deleting tag' $1 'from local using command: git tag -d tagName;'; \
			git tag -d $1; \
		}; f"

The usage looks like:

-->git delete-tag v1.0-DeleteMe
deleting tag v1.0-DeleteMe from remote/origin ausing command: git push --delete origin tagName;
 - [deleted]             v1.0-DeleteMe
deleting tag v1.0-DeleteMe from local using command: git tag -d tagName;
Deleted tag 'v1.0-DeleteMe' (was 300d3ef22)

Solution 24 - Git

To delete a tag on your remote repository, you can use

git push <remote> :refs/tags/<tagname>

The way to interpret the above is to read it as the null value, the value before the colon is being pushed to remote tag name.

Solution 25 - Git

Here is a local testcase to test it locally without messing with a remote:

~/p $ mkdir gittest    
~/p/git $ cd gittest/
~/p/gittest $ git init
Initialized empty Git repository in /Users/local_user/p/gittest/.git/
 ~/p/gittest $ touch testfile.txt
 ~/p/gittest $ git add testfile.txt
 ~/p/gittest $ git commit -m "initial commit"
[master (root-commit) 912ce0e] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 testfile.txt
 ~/p/gittest $ git tag
 ~/p/gittest $ git tag -a testtag
 ~/p/gittest $ git tag
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
b0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag
 ~/p/gittest $ cd ..
 ~/p $ mkdir gitbare
 ~/p $ cd gitbare
 ~/p/gitbare $ git init --bare
Initialized empty Git repository in /Users/local_user/p/gitbare/
 ~/p/gitbare $ cd ..
 ~/p $ cd gittest/
 ~/p/gittest $ git remote add origin /Users/local_user/p/gitbare
 ~/p/gittest $ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 215 bytes | 215.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /Users/local_user/p/gitbare
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
 ~/p/gittest $ git push origin testtag
Counting objects: 1, done.
Writing objects: 100% (1/1), 163 bytes | 163.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To /Users/local_user/p/gitbare
 * [new tag]         testtag -> testtag
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master
b0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag
 ~/p/gittest $ git push -d origin testtag
To /Users/local_user/p/gitbare
 - [deleted]         testtag
 ~/p/gittest    git tag -d testtag
Deleted tag 'testtag' (was b0a6c15)
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master

Solution 26 - Git

There are a lot of good answers here already, but if you ever need to delete all the tags, this one liner using PowerShell can be used:

foreach($tag in (git tag)) { git tag -d $tag.Trim(); git push origin :refs/tags/$tag }

Here, we get the list of all tags, delete each local tag followed by deleting the remote tag (tested on GitHub).

Solution 27 - Git

This worked for me

git push --force origin refs/tags/<tag_name>:refs/tags/<tag_name>


All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmarkdorisonView Question on Stackoverflow
Solution 1 - GitAdam FrancoView Answer on Stackoverflow
Solution 2 - GitquexerView Answer on Stackoverflow
Solution 3 - GitAlex DeanView Answer on Stackoverflow
Solution 4 - GitSiddhartha MukherjeeView Answer on Stackoverflow
Solution 5 - GitAyubView Answer on Stackoverflow
Solution 6 - GitMahmoud ZaltView Answer on Stackoverflow
Solution 7 - GitVonCView Answer on Stackoverflow
Solution 8 - GitAndreaView Answer on Stackoverflow
Solution 9 - GitL Y E S - C H I O U K HView Answer on Stackoverflow
Solution 10 - GitAlex Vazquez FenteView Answer on Stackoverflow
Solution 11 - GitIgniteCodersView Answer on Stackoverflow
Solution 12 - GitTonyHView Answer on Stackoverflow
Solution 13 - GitMeganZhouView Answer on Stackoverflow
Solution 14 - GitChris SpragueView Answer on Stackoverflow
Solution 15 - GitTonyHView Answer on Stackoverflow
Solution 16 - GitLucent FoxView Answer on Stackoverflow
Solution 17 - GitrsennaView Answer on Stackoverflow
Solution 18 - GitRichard VenableView Answer on Stackoverflow
Solution 19 - GitDimitar VlasevView Answer on Stackoverflow
Solution 20 - GitWappenullView Answer on Stackoverflow
Solution 21 - GitHomerMView Answer on Stackoverflow
Solution 22 - GitMernXLView Answer on Stackoverflow
Solution 23 - Gitranma2913View Answer on Stackoverflow
Solution 24 - GitasafecaView Answer on Stackoverflow
Solution 25 - GitAdnan YView Answer on Stackoverflow
Solution 26 - GitNeil P.View Answer on Stackoverflow
Solution 27 - Gitkarthi190View Answer on Stackoverflow