如何删除远程标签?


Answers:


5742

您只需要将“空”引用推送到远程标记名称:

git push origin :tagname

或者,更富表现力的是,使用--delete选项(或者-d如果您的git版本低于1.8.0):

git push --delete origin tagname

请注意,git具有标签名称空间和分支名称空间,因此您可以对分支和标签使用相同的名称。如果要确保不会意外删除分支而不是标签,则可以指定完整引用,它绝不会删除分支:

git push origin :refs/tags/tagname

如果还需要删除本地标签,请使用:

git tag --delete tagname

背景

将分支,标记或其他引用推送到远程存储库涉及指定“哪个存储库,哪个源,哪个目标?”。

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

一个真实的示例,其中您将master分支推到原点的master分支是:

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

由于默认路径,可以将其缩短为:

git push origin master:master

标签的工作方式相同:

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

也可以缩短为:

git push origin release-1.0:release-1.0

通过省略源引用(冒号之前的部分),将“无”推到目标,删除远程端的引用。


187
+1既回答问题并解释一般情况,又详细说明了未删节语法的含义
Peter Host

77
并且以防万一有人想知道如何在一次使用空格简单列出它们的同时删除多个标记,例如git push --delete origin tag1 tag2。删除本地标签同样有效git tag -d tag1 tag2
dVaffection 2014年

8
如果标签名称与分支名称冲突,则最终可能会删除分支。哈哈。查看第二个答案-更环保
zuba

1
@EmmaHe A tag仅附加到单个提交。因此,分支名称无关紧要。
cb2

1
知道git tag -d `git tag`将删除所有本地标签也很有趣。这同样适用于git push --delete origin `git tag`假设你拉到本地远程标签。在测试环境中这很方便。
DarkFranX

382

一种更直接的方法是

git push --delete origin YOUR_TAG_NAME

在这种情况下,IMO前缀冒号语法有点奇怪


4
我认为这是正确的方法……其他语法在我看来更像是骇客。
Luigi R. Viggiano

11
是的,这很简单并且有效。尽管我通过指定变量部分来澄清答案:git push --delete origin "TAGNAME",其中TAGNAME是原始标签的名称。
Teemu Leisti

12
这可行。一个附加功能:如果您有一个分支和一个具有相同名称的标签,则可以tag在标签名称之前添加单词,以确保获得标签而不是分支。
andypaxo

9
@andypaxo该命令采用的是refspecs,正确的方法是在标记之前加上refs/tags/,如下所示:refs/tags/v2.3.1
p3lim

我以某种方式在远程服务器上创建了“坏”标签名称,其中包含特殊字符,因此我无法与之同步,因此请根据您的建议将其删除:git push --delete origin“ service-<default>- 151“,不能不使用intellij,不使用隐藏,不使用sourceTree来将其删除。谢谢 !
Dmitri Algazin

215

如果您有一个远程标签v0.1.0要删除,而您的远程标签是origin,则只需:

git push origin :refs/tags/v0.1.0

如果还需要在本地删除标签:

git tag -d v0.1.0

有关Git 删除异常语法的解释,请参见Adam Franco的答案:


2
这也适用于jgit。:tag简写不适用于jgit
rynop 2012年

我有fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1...?
Chaim Eliyah 2016年

3
@ChaimEliyah,您有一个斜杠,也许这是您的问题
Joffrey

5
更好的答案,因为如果您有一个分支和一个称为相同的标签,这也将起作用。
Erik A. Brandstadmoen '18年

只是:tagname应该用于远程删除。
Acumenus

106

删除所有本地标签并获取远程标签列表

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

删除所有远程标签

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

清理本地标签

git tag -l | xargs git tag -d

2
如何从本地和远程存储库中删除所有标签。这就是我想要的,谢谢!
豪尔赫·奥尔皮内尔

git fetch,删除远程,然后清理本地人,效果很好!
DiegoRBaquero

缓慢但最直接的方法
朗讯·福克斯

33

要从远程存储库中删除标签:

git push --delete origin TAGNAME

您可能还想在本地删除标签:

git tag -d TAGNAME

因此,只有一条线可以做到:git push --delete origin TAGNAME && git tag -d TAGNAME
sakurashinken


23
git tag -d your_tag_name
git push origin :refs/tags/your_tag_name
  1. 第一行,your_tag_name本地存储库中删除。
  2. 第二行,your_tag_name远程仓库中删除。
  3. 在GitHub Releases部分中按Discard draft按钮。

在此处输入图片说明


2
尽管此命令可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以改善其长期价值。如何回答
Popo

20

删除本地标签“ 12345”

git tag -d 12345

删除远程标签“ 12345”(例如;也是GitHub版本)

git push origin :refs/tags/12345

替代方法

git push --delete origin tagName
git tag -d tagName

在此处输入图片说明


15

请注意,如果您有一个名为remote tag的远程分支,则这些命令是不明确的:

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

因此,您必须使用以下命令删除标签:

git push origin :refs/tags/<tag>

而这个删除分支:

git push origin :refs/heads/<branch>

如果没有,您将得到如下错误:

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

简短而简洁。这篇帖子以及MeganZhou的出现是我们为什么遇到问题的答案,分支名称和标记名称相同。我删除了本地标签,并推送到:refs / tags,一切都很好。
rwheadon

12

数千种远程标签的处理速度提高了100倍

在阅读完这些答案后,需要删除超过11,000个标签,我了解到这些方法是依赖或xargs花费太长时间的,除非您需要花费数小时。

挣扎,我发现了两个更快的方法。对于这两种方式,都以git taggit ls-remote --tags列出要在遥控器上删除的标签。在下面的示例中,您可以省略或替换sorting_proccessing_etc为所需的任何greping,sorting,tailing或heading(例如 grep -P "my_regex" | sort | head -n -200 etc):


第一种方法到目前为止最快,可能比使用快20到100倍xargs,并且一次至少可以处理数千个标签。

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

这是如何运作的?普通的,行分隔的标签列表将转换为单行的,以空格分隔的标签,每个标签前面都带有:so。。。

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

git push与该format标记一起使用不会任何内容推入每个远程引用,而将其删除(这种方式的常规格式是local_ref_path:remote_ref_path)。

方法2分解为同一页上其他位置的单独答案


在这两种方法之后,您可能还希望删除本地标签。这要快得多,所以我们可以回到使用xargsgit tag -d,这已经足够了。

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

或类似于远程删除:

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

您应该将其分为几个不同的答案。毫无疑问,一行上有多个标签的答案无疑是批量标签删除的正确答案。在几乎其他任何地方都很难找到此信息。即使知道我在寻找什么,我也很难在git帮助页面中找到它:)因此,对您表示敬意,并突出显示它是正确的答案,然后将GitHub API移到另一个位置。最后,批量删除标签可以在本地与空格分隔的标签一起使用(摆脱冒号)
CubanX

感谢您的好评和建议。我将拆分。我不理解您对本地标签删除的评论。我不认为我的最终命令摘要使用任何冒号,但我在移动设备上,因此可能缺少某些内容。
TonyH

抱歉,我的意思是您要删除远程标签的操作可以与删除本地标签一起使用,一次提供整个列表。:)而不是git push origin:tag1:tag2等,您可以使用git tag --delete tag1 tag2 tag3这样的方式进行总清理。再次感谢您!
CubanX

11

如果您使用SourceTree(一个出色的Git GUI),则可以通过以下操作轻松地在没有命令行的情况下执行此操作:

  1. 在SourceTree中打开您的存储库
  2. 选择并展开左侧的“标签”标签
  3. 右键单击要删除的标签
  4. 选择“删除YOUR_TAG_NAME”
  5. 在验证窗口中,选择“从遥控器中删除标签”

现在,您的YOUR_TAG_NAME将从本地存储库和所有远程存储中删除-不管是GitHub,BitBucket还是您作为该存储库的远程存储列出的其他任何位置。

另外,如果您在本地删除了一个标签,但未在远程原点上删除它,并且您想在各处删除它,那么只需创建一个新标签,该标签具有相同的名称,并在与原点相同的提交时附加。然后,重复上述步骤以删除所有地方。


奇迹般有效。谢谢!
Native_Mobile_Arch_Dev


7

如果您使用的是PowerShell,并且要删除其中一堆:

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

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

当然,您也可以在删除之前过滤它们:

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

那是一个很好的正则表达式示例。谢谢你,先生
尤努斯

7

正如@CubanX所建议的那样,我已将答案与原始答案分开:

这是一种比xargs调整速度快几倍并且可以通过调整进行扩展的方法。它使用Github API(个人访问令牌)并利用实用程序parallel

git tag | sorting_processing_etc | parallel --jobs 2 curl -i -X DELETE \ 
https://api.github.com/repos/My_Account/my_repo/git/refs/tags/{} -H 
\"authorization: token GIT_OAUTH_OR_PERSONAL_KEY_HERE\"  \
-H \"cache-control: no-cache\"`

parallel有许多操作模式,但通常会并行化您提供的任何命令,同时允许您设置进程数限制。您可以更改--jobs 2参数以允许更快的操作,但是我对Github的速率限制有问题,目前该速率限制为5000 / hr,但似乎也有一个未记录的短期限制。


之后,您可能还希望删除本地标签。这要快得多,所以我们可以回到使用xargsgit tag -d,这已经足够了。

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

这似乎比公认的答案复杂得多。有什么好处?
theUtherSide

2
如果您需要删除几千个标签,那么速度是10-100倍
TonyH

谢谢您的澄清。OP询问要删除单个标签。我无法想象为什么有人会为单个标签使用这种方法。对于另一个涉及删除许多标签的问题,也许这个答案更好
TheUtherSide

我不认为它存在。我可以创建它来回答自己。您是否认为合适?
TonyH

1
我做!实际上,我认为这是一种相当普遍的做法。
theUtherSide

6

其他答案指出了如何完成此操作,但是由于这是一个远程存储库,因此应牢记后果。

git tag手册页(在“ 重新标记” 部分)中很好地说明了如何有礼貌地将更改通知远程仓库的其他用户。他们甚至提供了方便的公告模板,用于传达其他人应如何获得您的更改。


6

我想删除除与模式匹配的那些标签以外的所有标签,以便可以删除除生产标签的最后几个月以外的所有标签,这是我曾经获得巨大成功的方法:

删除所有远程标记并从删除中排除表达式

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

删除所有本地标签并从删除中排除表达式

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

5

简单的脚本可从本地和原始位置删除给定标签。检查标签是否确实存在。

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

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

如何使用:

  • 创建外壳脚本文件(例如git-tag-purge.sh)并粘贴内容。
  • chmod您的脚本文件以使其可执行。
  • 使脚本全局可用
  • cd到你的git项目
  • 通话脚本(例如
    $> git-tag-purge.sh tag_name

4

似乎xargs已经做了很多工作。回头看一下这个线程,我猜xargs您遇到的缓慢是因为使用了原始答案xargs -n 1不需要时。

这等效于您的方法一,只是xargs自动处理最大命令行长度:

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

xargs也可以并行运行进程。方法2 xargs

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

上面最多使用5个进程来处理每个进程中最多100个参数。您可以对这些参数进行试验,以找到最适合您需要的参数。


有趣。您每天都会学习有关Unix命令的新知识。我需要用这种替代方法测试用例。
TonyH

4

如果您创建了一个以字符开头的标签,例如#ST002,您可能会发现u无法使用常规模式删除。即

git tag -d #STOO2

不会删除标签,而是像这样将其包装在String Literal中

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

它将被删除。希望它可以帮助犯过使用编写标签名称的错误的人。


2

这是一个本地测试用例,可以在本地进行测试而不会与远程混乱:

~/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
testtag
 ~/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
 ~/p/gittest

1

您好,我只是想分享一个我创建的别名,该别名具有相同的功能:

将以下内容添加到您的〜/ .gitconfig中

[alias]
    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"

用法如下所示:

-->git delete-tag v1.0-DeleteMe
deleting tag v1.0-DeleteMe from remote/origin ausing command: git push --delete origin tagName;
To https://github.com/jsticha/pafs
 - [deleted]             v1.0-DeleteMe
deleting tag v1.0-DeleteMe from local using command: git tag -d tagName;
Deleted tag 'v1.0-DeleteMe' (was 300d3ef22)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.