如何删除远程标签?

如何删除已经推送的Git标签?

1789772 次浏览

您可以推送对远程标记名称的“空”引用:

git push origin :tagname

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

git push --delete origin tagname

请注意,git有标记命名空间和分支命名空间,因此您可以对分支和标记使用相同的名称。如果您想确保不会意外删除分支而不是标记,您可以指定永远不会删除分支的完整ref:

git push origin :refs/tags/tagname

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

git tag --delete tagname

背景

将分支、标签或其他ref推送到远程存储库涉及指定“哪个存储库、什么来源、什么目的地?”

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

将主分支推送到源的主分支的真实示例是:

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

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

如果您有一个远程标签v0.1.0要删除,并且您的远程标签是origin,那么只需:

git push origin :refs/tags/v0.1.0

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

git tag -d v0.1.0

有关Git不寻常的:删除语法的解释,请参阅亚当·弗兰科的回答

更直接的方法是

git push --delete origin YOUR_TAG_NAME

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

其他答案指出了如何实现这一点,但您应该记住后果,因为这是一个远程存储库。

关于复试部分的git标签手册页很好地解释了如何礼貌地通知远程存储库的其他用户更改。他们甚至提供了一个方便的公告模板来交流其他人应该如何获得您的更改。

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

git tag -l | xargs git tag -dgit fetch

删除所有远程标签

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

清理本地标签

git tag -l | xargs git tag -d

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

git push --delete origin TAGNAME

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

git tag -d TAGNAME

如果您在Git存储库中创建了一个名为release01的标签,您可以通过执行以下操作将其从存储库中删除:

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

要从Mercurial存储库中删除一个:

hg tag --remove featurefoo

请参考https://confluence.atlassian.com/pages/viewpage.action?pageId=282175551

请注意,如果您有一个名为远程标签的远程分支,这些命令是模棱两可的:

git push origin :tagnamegit 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>'

从您的终端,这样做:

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

现在去Github.com刷新,它们消失了。

为数千个远程标签提供高达100倍的速度

在阅读了这些答案,同时需要删除超过11,000个标签后,我了解到这些方法依赖或xargs需要太长时间,除非你有几个小时可以燃烧。

苦苦挣扎,我找到了两种更快的方法。对于两者,从git taggit ls-remote --tags开始,列出你想在遥控器上删除的标签。在下面的例子中,你可以省略或替换sorting_proccessing_etc,用任何你想要的greping、sorting、tailing或heading(e. g.grep -P "my_regex" | sort | head -n -200git ls-remote --tags0):


第一种方法是迄今为止最快的,也许比使用xargs20到100次,并且一次至少使用几个标签。

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

这是如何工作的?正常的、行分隔的标签列表被转换为一行空格分隔的标签,每个标签都以:开头,因此 . . .

tag1   becomestag2   ======>  :tag1 :tag2 :tag3tag3

git push与此格式标记一起使用会将什么都没有推送到每个远程引用中,并将其擦除(以这种方式推送的正常格式是local_ref_path:remote_ref_path)。

方法二被分解为一个单独的答案在同一页的其他地方


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

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

OR类似于远程删除:

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

从本地和源位置删除给定标签的简单脚本。检查标签是否真的存在。

if [ $(git tag -l "$1") ]; thengit tag --delete  $1git push --delete origin $1
echo done.elseecho tag named "$1" was not foundfi

如何使用:

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

看起来xargs已经做了很多工作。回顾这篇文章,我猜你经历的xargs的缓慢是因为最初的答案在不需要的时候使用了xargs -n 1

这相当于您的方法1,除了xargs自动处理最大命令行长度:

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

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

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

上面使用最多5个进程来处理每个进程中最多100个参数。您可以尝试参数以找到最适合您需求的方法。

如果您使用的是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 $_ }

正如@CubanX建议的那样,我把这个答案从我的原始答案中分离出来:

这是一个比xargs快几倍的方法,并且可以通过调整来扩展更多。它使用github API,一个个人访问令牌,并利用实用程序#1

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\"`

#0有许多操作模式,但通常会并行化您给它的任何命令,同时允许您设置进程数量的限制。您可以更改--jobs 2参数以允许更快的操作,但我对Github的费率限制有问题,目前为5000/小时,但似乎也有未记录的短期限制。


在这之后,您可能也想删除本地标签。这要快得多,所以我们可以回到使用xargsgit tag -d,这就足够了。

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

我想删除所有标签,除了那些匹配模式的标签,这样我就可以删除除了最后几个月的生产标签之外的所有标签,这是我曾经取得巨大成功的地方:

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

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

删除本地标签'12345'

git tag -d 12345

删除远程标签'12345'(例如;GitHub版本)

git push origin :refs/tags/12345

替代方法

git push --delete origin tagNamegit tag -d tagName

在此处输入图片描述

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

git tag -d #STOO2

不会删除标签,而是像这样将其包装在字符串文字

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

这将使它被删除。希望它能帮助那些犯了使用#编写标签名称的错误的人。

这是一个本地测试用例,可以在本地测试它,而不会干扰远程:

~/p $ mkdir gittest~/p/git $ cd gittest/~/p/gittest $ git initInitialized 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 commit1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 testfile.txt~/p/gittest $ git tag~/p/gittest $ git tag -a testtag~/p/gittest $ git tagtesttag~/p/gittest $ git show-ref912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/masterb0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag~/p/gittest $ cd ..~/p $ mkdir gitbare~/p $ cd gitbare~/p/gitbare $ git init --bareInitialized 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 masterCounting 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 -> masterBranch 'master' set up to track remote branch 'master' from 'origin'.~/p/gittest $ git push origin testtagCounting 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-ref912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/masterb0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag~/p/gittest $ git push -d origin testtagTo /Users/local_user/p/gitbare- [deleted]         testtag~/p/gittest    git tag -d testtagDeleted tag 'testtag' (was b0a6c15)~/p/gittest $ git show-ref912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master~/p/gittest

如果您使用SourceTree-一个很棒的Git GUI-那么您可以通过执行以下操作轻松地在没有命令行的情况下完成此操作:

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

YOUR_TAG_NAME现在将从您的本地存储库和所有远程存储库中删除——无论是GitHub、BitBucket还是您列为该存储库远程存储的任何其他地方。

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

只是想分享我创建的别名,它做同样的事情:

将以下内容添加到您的~/.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-DeleteMedeleting tag v1.0-DeleteMe from remote/origin ausing command: git push --delete origin tagName;To https://github.com/jsticha/pafs- [deleted]             v1.0-DeleteMedeleting tag v1.0-DeleteMe from local using command: git tag -d tagName;Deleted tag 'v1.0-DeleteMe' (was 300d3ef22)
git tag -d your_tag_namegit push origin :refs/tags/your_tag_name

第一行从当地 repo中删除your_tag_name,第二行从远程 repo中删除your_tag_name

对于那些使用GitHub的人来说,还需要一个步骤:弃风输入图片描述

要删除远程存储库上的标记,您可以使用

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

解释上述内容的方法是将其读取为空值,即冒号之前的值被推送到远程标记名称。

对于陆龟git用户,在数百个标签的规模下,您可以使用UI一次删除多个标签,但UI很好地隐藏在上下文菜单下。

从资源管理器窗口右键单击->浏览引用->右键单击ref/refmotes/name->选择删除远程标签

在此处输入图片描述

https://tortoisegit.org/docs/tortoisegit/tgit-dug-browse-ref.html

git push --delete origin $TAGNAME是正确的方法(除了本地删除)。

但是:确保使用Git 2.31+(2021年第一季度)。

#0man)应该被诊断为错误,但却变成了匹配的推送,Git 2.31(2021年第一季度)已经纠正了这一点。

提交20e4164(2021年2月23日)byJunio C Hamano(#0)
(2021年2月25日提交1400458合并为Junio C Hamano----#0----

#0:不要将--delete ''变成匹配的推送

作者:Tilman Vogel

当我们添加语法糖“#0man)<ref>到“<ref>0”<ref>1作为规范<ref>2<ref>3的同义词时:<ref>4处的语法(“builtin-push<ref>5<ref>6--delete作为: foo的语法糖”,2009-12-30,Git v1.7.0-rc0--<ref>7),我们没有足够小心以确保<ref>不为空。

盲目地将“--delete <ref>”重写为“:<ref>”意味着空字符串<ref>会导致refspec“:”,这是要求“匹配”推送的语法,不会删除任何内容。

更糟糕的是,如果有匹配的引用可以快进,它们就会过早发布,即使用户觉得他们还没有准备好被推出,这将是一场真正的灾难。

这招对我管用

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

这两个步骤运行良好:

# 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

这里已经有很多很好的答案,但如果您需要删除所有标签,可以使用以下使用PowerShell的一个班轮:

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

在这里,我们获取所有标签的列表,删除每个本地标签,然后删除远程标签(在GitHub上测试)。