关于git:如何删除远程标签?

How to delete a remote tag?

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


只需将"空"引用推送到远程标记名:

1
git push origin :tagname

或者,更具体地说,使用--delete选项(如果您的git版本早于1.8.0,则使用-d选项):

1
git push --delete origin tagname

注意,Git有标记名称空间和分支名称空间,因此可以对分支和标记使用相同的名称。如果要确保不会意外地删除分支而不是标记,可以指定完全引用,它将永远不会删除分支:

1
git push origin :refs/tags/tagname

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

1
git tag --delete tagname

。背景

将分支、标记或其他引用推送到远程存储库需要指定"哪个repo、哪个源、哪个目标?"

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

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

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

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

1
git push origin master:master

标签的工作方式相同:

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

也可以缩短为:

1
git push origin release-1.0:release-1.0

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


更直接的方法是

1
git push --delete origin YOUR_TAG_NAME

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


如果您要删除一个远程标记v0.1.0,而您的远程标记是origin,那么简单地:

1
git push origin :refs/tags/v0.1.0

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

1
git tag -d v0.1.0

参见亚当·弗兰科的回答,了解关于git不寻常的:删除语法的解释。


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

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

删除所有远程标记

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

清除本地标记

1
git tag -l | xargs git tag -d


要从远程存储库中删除标记,请执行以下操作:

1
git push --delete origin tagname

您还可能希望在本地删除标记:

1
git tag -d TAGNAME


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

1
2
3
4
git fetch
git tags
git tag -d {tag-name}
git push origin :refs/tags/{tag-name}

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


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

1
2
git push origin :tagname
git push --delete origin tagname

因此,必须使用此命令删除标记:

1
git push origin :refs/tags/<tag>

这一个删除了分支:

1
git push origin :refs/heads/<branch>

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

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


删除本地标记"12345"

1
git tag -d 12345

号删除远程标记"12345"(例如,GitHub版本也一样)

1
git push origin :refs/tags/12345

号替代方法

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

enter image description here


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

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

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

1
hg tag --remove featurefoo

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


对于数千个远程标记,速度快100倍

在阅读了这些答案后,我需要删除超过11000个标签,我学会了依赖这些方法,或者xargs花的时间太长,除非你有时间去燃烧。

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

第一种方法是迄今为止最快的,可能比使用xargs快20到100倍,一次至少使用几千个标签。

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

这是怎么工作的?普通的、行分隔的标签列表被转换为一行空格分隔的标签,每个标签都用:so预先填充。…

1
2
3
tag1   becomes
tag2   ======>  :tag1 :tag2 :tag3
tag3

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

方法二作为一个单独的答案分列在同一页的其他地方。

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

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

或类似于远程删除:

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


如果您使用sourcetree(一个伟大的Git GUI),那么您可以通过执行以下操作轻松地在不使用命令行的情况下执行此操作:

  • 在sourcetree中打开存储库
  • 选择并展开左侧的"标记"选项卡
  • 右键单击要删除的标记
  • 选择"删除您的标记名"
  • 在验证窗口中,选择"从远程删除标记"
  • 您的_标记_名称现在将从本地存储库和所有远程设备中删除-无论是GitHub、BitBucket,还是您列为该存储库远程设备的其他任何地方。

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


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

    在重新标记部分的Git标签手册页中,有一个很好的解释,说明了如何礼貌地将更改通知远程回购的其他用户。他们甚至提供了一个方便的公告模板,用于交流其他人应该如何获得您的更改。


    我想删除所有的标签,除了那些与模式匹配的标签,这样我就可以删除除过去几个月的生产标签以外的所有标签,以下是我成功使用的方法:

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

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

    从删除中删除所有本地标记和排除表达式

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


    正如@cubanx所建议的,我将这个答案与我的原始答案分开:

    这是一种比xargs快几倍的方法,可以通过调整来扩大规模。它使用个人访问令牌Github API,并利用实用工具parallel

    1
    2
    3
    4
    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/小时,但似乎也有未记录的短期限制。

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

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


    似乎xargs已经做了很多工作。回过头来看,我猜你对xargs的反应很慢,因为最初的答案使用xargs -n 1,而实际上并不需要。

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

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

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

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

    上面最多使用5个进程来处理每个进程中最多100个参数。你可以用这些论点进行实验,找出最适合你需要的东西。


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

    1
    2
    3
    4
    5
    6
    7
    8
    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项目
    • 调用脚本(如
      1
      $>git-tag-purge.sh tag_name

      )


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

    第一行从本地repo删除your_tag_name,第二行从远程repo删除。现在,您的_标签已从本地和远程repo中完全删除,但有时您可能需要删除已删除的标签,该标签由GitHub在您的发布部分手动起草。


    如果您使用的是PowerShell,并且希望删除其中一组:

    1
    2
    3
    4
    5
    # Local tags:
    git tag -l | foreach { git tag -d $_ }

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

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

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

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

    1
    git tag -d #STOO2

    不会删除标记,而是像这样用字符串文字包装它

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

    这将删除它。希望它能帮助犯了错误的人写标签名。


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    ~/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

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

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

    1
    2
    3
    4
    5
    6
    7
    [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"

    用法如下:

    1
    2
    3
    4
    5
    6
    -->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)