【发布时间】:2011-07-25 17:08:44
【问题描述】:
如何删除已经推送的Git标签?
【问题讨论】:
如何删除已经推送的Git标签?
【问题讨论】:
这对我有用
git push --force origin refs/tags/<tag_name>:refs/tags/<tag_name>
【讨论】:
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)<ref>添加到“git push”时(man) 作为同义词到规范的git push remote(man) :f517f1f 的语法(“builtin-push:add(man)--delete作为语法:foo 的糖,2009 年 12 月 30 日,Git v1.7.0-rc0 -- merge),我们没有仔细确保<ref>不为空。盲目地将“--delete”重写为“:”意味着空字符串
<ref>会导致refspec“:”,这是请求“匹配”推送的语法,不会删除任何内容。更糟糕的是,如果有匹配的 ref 可以快进,即使用户觉得他们还没有准备好被推出,它们也会过早发布,这将是一场真正的灾难。
【讨论】:
对于tortoise git用户,数百个标签的规模,你可以使用UI一次删除多个标签,但UI很好地隐藏在上下文菜单下。
从资源管理器窗口右键单击 -> 浏览引用 -> 右键单击 ref/refmotes/name -> 选择 '删除远程标签'
见https://tortoisegit.org/docs/tortoisegit/tgit-dug-browse-ref.html
【讨论】:
【讨论】:
要删除远程存储库上的标签,您可以使用
git push <remote> :refs/tags/<tagname>
上面的解释方式是把它读取为空值,冒号前的值被推送到远程标签名。
【讨论】:
您可以将“空”引用推送到远程标记名称:
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
通过省略源引用(冒号前的部分),您将“无”推送到目标,删除远程端的引用。
【讨论】:
git push --delete origin tag1 tag2。同样适用于本地标签删除git tag -d tag1 tag2
git tag -d `git tag` 将删除所有本地标签也很有趣。假设您在本地提取远程标签,git push --delete origin `git tag` 同样适用。这在测试环境中很方便。
只是想分享一个我创建的别名,它做同样的事情:
将以下内容添加到您的~/.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)
【讨论】:
如果您使用 SourceTree - 一个很棒的 Git GUI - 那么您可以通过以下操作轻松完成此操作而无需命令行:
YOUR_TAG_NAME 现在将从您的本地存储库和所有远程存储库中删除 - 无论是 GitHub、BitBucket 还是您列为该存储库的远程存储库的任何其他位置。
另外,如果您在本地而不是远程源上删除了一个标签,并且您想在任何地方删除它,那么只需创建一个具有相同名称的新标签,并在与源相同的提交处附加。然后,重复上述步骤,将所有地方删除。
【讨论】:
如果你有一个远程标签v0.1.0要删除,而你的远程是origin,那么很简单:
git push origin :refs/tags/v0.1.0
如果还需要在本地删除标签:
git tag -d v0.1.0
请参阅 Adam Franco's answer 了解 Git 不寻常的 : 删除语法的解释。
【讨论】:
fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1 ...?
:tagname 即可远程删除。
这是一个本地测试用例,可以在本地测试它而不会弄乱远程:
~/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
【讨论】:
如果您创建了一个以 # 字符开头的标签,例如#ST002,您可能会发现您无法使用正常模式删除。即
git tag -d #STOO2
不会删除标记,而是将其包装在 String Literal 中,就像这样
git tag -d "#ST002" or git tag -d '#ST002'
这将使它被删除。希望它能帮助那些错误地使用 # 来编写标签名称的人。
【讨论】:
我想删除所有标签,除了那些匹配模式的标签,这样我就可以删除除了最后几个月的生产标签之外的所有标签,这就是我过去取得巨大成功的方法:
删除所有远程标签并从删除中排除表达式
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
【讨论】:
在阅读了这些需要删除超过 11,000 个标签的答案后,我了解到这些方法依赖于或 xargs 花费的时间太长,除非您有几个小时的时间。
苦苦挣扎,我找到了两种快得多的方法。对于这两者,从git tag 或git ls-remote --tags 开始列出您要在遥控器上删除的标签。在下面的示例中,您可以省略或替换 greping、sorting、tailing 或 heading 您想要的任何 sorting_proccessing_etc(eg grep -P "my_regex" | sort | head -n -200 等):
xargs 快 20 到 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)。
使用这两种方法后,您可能还想删除本地标签。
这要快得多,所以我们可以重新使用xargs 和git tag -d,这就足够了。
git tag | sorting_processing_etc | xargs -L 1 git tag -d
或类似于远程删除:
git tag -d $(< git tag | sorting_processing_etc | paste -sd " ")
【讨论】:
正如@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/小时,但似乎也有一个未记录的短期限制。
在此之后,您可能还想删除本地标签。
这要快得多,所以我们可以重新使用xargs 和git tag -d,这就足够了。
git tag | sorting_processing_etc | xargs -L 1 git tag -d
【讨论】:
如果您使用的是 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 $_ }
【讨论】:
似乎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 个参数。您可以对这些参数进行试验,以找到最适合您需求的参数。
【讨论】:
从本地和原始位置删除给定标签的简单脚本。 检查标签是否真的存在。
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 tag_name)
【讨论】:
从您的终端执行以下操作:
git fetch
git tags
git tag -d {tag-name}
git push origin :refs/tags/{tag-name}
现在去 Github.com 刷新一下,它们就消失了。
【讨论】:
删除所有本地标签并获取远程标签列表:
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 存储库中创建了一个名为 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
【讨论】:
请注意,如果您有一个名为远程标记的远程分支,则这些命令是不明确的:
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>'
【讨论】:
更直接的方法是
git push --delete origin YOUR_TAG_NAME
在这种情况下,IMO 前缀冒号语法有点奇怪
【讨论】:
git push --delete origin "TAGNAME",其中 TAGNAME 是原始标签的名称。
tag这个词,以确保你得到的是标签,而不是分支。
refs/tags/,就像这样:refs/tags/v2.3.1。
要从远程存储库中删除标签:
git push --delete origin TAGNAME
您可能还想在本地删除标签:
git tag -d TAGNAME
【讨论】:
git push --delete origin TAGNAME && git tag -d TAGNAME
其他答案指出了如何做到这一点,但您应该记住后果,因为这是一个远程存储库。
On Retagging 部分中的 git tag 手册页很好地解释了如何礼貌地通知远程 repo 的其他用户所做的更改。他们甚至提供了一个方便的公告模板,用于传达其他人应该如何获得您的更改。
【讨论】: