【问题标题】:How to delete a remote tag?如何删除远程标签?
【发布时间】:2011-07-25 17:08:44
【问题描述】:

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

【问题讨论】:

    标签: git git-tag


    【解决方案1】:

    这对我有用

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

    【讨论】:

      【解决方案2】:

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

      但是:确保使用 Git 2.31。

      "git push $there --delete"(man) 应该被诊断为错误,而是变成了匹配推送,已在 Git 2.31(2021 年第一季度)中更正。 p>

      参见Junio C Hamano (gitster)commit 20e4164(2021 年 2 月 23 日)。
      (由 Junio C Hamano -- gitster -- 合并到 commit 1400458,2021 年 2 月 25 日)

      push: 不要把 --delete '' 变成匹配的推送

      注意者:蒂尔曼·沃格尔

      当我们将语法糖“git push remote --delete(man)&lt;ref&gt; 添加到“git push”时(man) 作为同义词到规范的 git push remote(man)f517f1f 的语法(“builtin-push: add(man)--delete 作为语法:foo 的糖,2009 年 12 月 30 日,Git v1.7.0-rc0 -- merge),我们没有仔细确保 &lt;ref&gt; 不为空。

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

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          【解决方案4】:
          git tag -d your_tag_name
          git push origin :refs/tags/your_tag_name
          

          第一行从 local 存储库中删除 your_tag_name,第二行从 remote 存储库中删除 your_tag_name

          对于那些使用 GitHub 的人,还需要一个步骤:丢弃草稿

          【讨论】:

          • 虽然此命令可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。 How to Answer
          • 请注意,OP 没有在他们的问题中明确包含 github 标记,因此最后一步可能不适用于 OP。
          • 好点@Edric。我已经更新了答案。
          【解决方案5】:

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

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

          上面的解释方式是把它读取为空值,冒号前的值被推送到远程标签名。

          【讨论】:

            【解决方案6】:

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

            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
            

            背景

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

            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
            

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

            【讨论】:

            • +1 用于回答问题和解释一般情况,并详细说明未删节语法的含义
            • 如果有人想知道如何一次删除多个标签,您可以使用空格简单地列出它们,例如git push --delete origin tag1 tag2。同样适用于本地标签删除git tag -d tag1 tag2
            • 如果标签名称与分支名称冲突,您最终可能会删除您的分支。哈哈。看第二个答案 - 它更生态
            • 知道git tag -d `git tag` 将删除所有本地标签也很有趣。假设您在本地提取远程标签,git push --delete origin `git tag` 同样适用。这在测试环境中很方便。
            • 我们有 6700 多票的事实,而且它如此复杂,这可能意味着它可以重新设计。
            【解决方案7】:

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

            将以下内容添加到您的~/.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)
            

            【讨论】:

              【解决方案8】:

              如果您使用 SourceTree - 一个很棒的 Git GUI - 那么您可以通过以下操作轻松完成此操作而无需命令行:

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

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

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

              【讨论】:

              • 像魅力一样工作。谢谢!
              • 请注意,这是安全的,不会删除任何提交 - 只有标签本身
              【解决方案9】:

              如果你有一个远程标签v0.1.0要删除,而你的远程是origin,那么很简单:

              git push origin :refs/tags/v0.1.0
              

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

              git tag -d v0.1.0
              

              请参阅 Adam Franco's answer 了解 Git 不寻常的 : 删除语法的解释。

              【讨论】:

              • 这也适用于 jgit。 :tag 速记不适用于 jgit
              • 我收到了fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1 ...?
              • @ChaimEliyah 你有一个前导斜线,也许这是你的问题
              • 更好的答案,因为如果您有一个分支和一个称为相同的标签,这也可以工作。
              • 只需:tagname 即可远程删除。
              【解决方案10】:

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

              ~/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
              

              【讨论】:

                【解决方案11】:

                删除本地标签“12345”

                git tag -d 12345
                

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

                git push origin :refs/tags/12345
                

                替代方法

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

                【讨论】:

                  【解决方案12】:

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

                  git tag -d #STOO2
                  

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

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

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

                  【讨论】:

                    【解决方案13】:

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

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

                    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
                    

                    【讨论】:

                      【解决方案14】:

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

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

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


                      第一种方法是迄今为止最快的,可能比使用 xargs20 到 100 倍,并且一次至少可以处理几个 个标签。

                      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 与此格式标签一起使用会将nothing 推送到每个远程引用中,并将其擦除(这种方式推送的正常格式是local_ref_path:remote_ref_path)。

                      方法二被分解为一个单独的答案elsewhere on this same page


                      使用这两种方法后,您可能还想删除本地标签。 这要快得多,所以我们可以重新使用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 移至其他位置。最后,本地批量删除标签与空格分隔标签一起使用(去掉冒号)
                      • 感谢您的好评和建议。我会把这个分开。我不明白您对删除本地标签的评论。我不认为我的最终命令 sn-p 使用任何冒号,但我在移动设备上,所以可能会遗漏一些东西。
                      • 对不起,我的意思是你正在做的删除远程标签,删除本地标签,一次提供整个列表。 :) 而不是 git push origin :tag1 :tag2 等,你会做 git tag --delete tag1 tag2 tag3 这样你就可以进行彻底的清理。再次,非常感谢!
                      【解决方案15】:

                      正如@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 的 rate limits 有问题,目前为 5000/小时,但似乎也有一个未记录的短期限制。


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

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

                      【讨论】:

                      • 这似乎比公认的答案复杂得多。有什么好处?
                      • 如果需要删除几千个标签,那么速度要快10-100倍
                      • 感谢您的澄清。 OP询问有关删除单个标签的问题。我无法想象为什么有人会对单个标签使用这种方法。对于另一个涉及删除许多标签的问题,也许这个答案更好
                      • 我认为它不存在。我可以创建它来回答自己。你觉得这样合适吗?
                      • 我愿意!实际上,我认为这是一种相当普遍的做法。
                      【解决方案16】:

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

                      【讨论】:

                        【解决方案17】:

                        似乎xargs 已经做了很多工作。回顾这个帖子,我猜你遇到的xargs 的缓慢是因为原始答案在不需要时使用了xargs -n 1

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

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

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

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

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

                        【讨论】:

                        • 有趣。你每天都会学到一些关于 Unix 命令的新知识。我需要用这个替代方法测试我的用例。
                        【解决方案18】:

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

                        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
                        

                        使用方法:

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

                        【讨论】:

                          【解决方案19】:

                          从您的终端执行以下操作:

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

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

                          【讨论】:

                          • git 标签不是标签
                          【解决方案20】:

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

                          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
                          

                          【讨论】:

                          • 如何从本地和远程仓库中删除所有标签。这就是我要找的,谢谢!
                          • git fetch,删除远程,然后清理本地,效果很好!
                          • 慢,但最直接
                          【解决方案21】:

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

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

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

                          hg tag --remove featurefoo
                          

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

                          【讨论】:

                            【解决方案22】:

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

                            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 ,一切都很好。
                            【解决方案23】:

                            更直接的方法是

                            git push --delete origin YOUR_TAG_NAME
                            

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

                            【讨论】:

                            • 我认为这是正确的方法......其他语法对我来说更像是黑客。
                            • 是的,这很简单而且有效。虽然我会通过指定什么是可变部分来澄清答案:git push --delete origin "TAGNAME",其中 TAGNAME 是原始标签的名称。
                            • 这行得通。一个补充:如果你有一个分支和一个同名的标签,你可以在你的标签名前加上tag这个词,以确保你得到的是标签,而不是分支。
                            • @andypaxo 该命令采用的是refspecs,正确的方法是在标签前面加上refs/tags/,就像这样:refs/tags/v2.3.1
                            • 我以某种方式在远程服务器上创建了“坏”标签名称,其中包含特殊字符,所以我无法与之同步,所以只需根据您的建议将其删除: git push --delete origin “ service----151" ,不能用intellij,不能用stash,不能用sourceTree来删除它。谢谢!
                            【解决方案24】:

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

                            git push --delete origin TAGNAME
                            

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

                            git tag -d TAGNAME
                            

                            【讨论】:

                            • 所以一行来做这两个:git push --delete origin TAGNAME &amp;&amp; git tag -d TAGNAME
                            【解决方案25】:

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

                            On Retagging 部分中的 git tag 手册页很好地解释了如何礼貌地通知远程 repo 的其他用户所做的更改。他们甚至提供了一个方便的公告模板,用于传达其他人应该如何获得您的更改。

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2017-08-15
                              • 2021-11-11
                              • 2011-09-03
                              • 1970-01-01
                              • 1970-01-01
                              • 2011-10-13
                              • 2018-10-21
                              • 2020-02-18
                              相关资源
                              最近更新 更多