删除不再位于远程存储库上的本地git标记

删除不再位于远程存储库上的本地git标记,git,git-tag,Git,Git Tag,我们在git中使用标记作为部署过程的一部分。有时,我们希望通过从远程存储库中删除这些标记来清理它们 这很简单。一个用户在一组命令中删除本地标记和远程标记。我们有一个结合了这两个步骤的小shell脚本 第二、第三、第四,。。。用户现在拥有不再反映在远程服务器上的本地标记 我正在寻找一个类似于git remote prune origin的命令,它清理本地跟踪的分支,远程分支已被删除 或者,可以使用列出远程标记的简单命令与通过git tag-l返回的本地标记进行比较。好问题:我没有一个完整的答案 也

我们在git中使用标记作为部署过程的一部分。有时,我们希望通过从远程存储库中删除这些标记来清理它们

这很简单。一个用户在一组命令中删除本地标记和远程标记。我们有一个结合了这两个步骤的小shell脚本

第二、第三、第四,。。。用户现在拥有不再反映在远程服务器上的本地标记

我正在寻找一个类似于git remote prune origin的命令,它清理本地跟踪的分支,远程分支已被删除


或者,可以使用列出远程标记的简单命令与通过git tag-l返回的本地标记进行比较。

好问题:我没有一个完整的答案

也就是说,您可以通过git ls remote获得远程标记列表。要列出origin引用的存储库中的标记,请运行:

git ls-remote --tags origin
返回哈希和友好标记名的列表,如:

94bf6de8315d9a7b22385e86e1f5add9183bcb3c        refs/tags/v0.1.3
cc047da6604bdd9a0e5ecbba3375ba6f09eed09d        refs/tags/v0.1.4
...
2f2e45bedf67dedb8d1dc0d02612345ee5c893f2        refs/tags/v0.5.4
您当然可以组合一个bash脚本,将此列表生成的标记与本地的标记进行比较。看看gitshowref-tags,它以与gitlsremote相同的形式生成标记名

另一方面,git show ref有一个选项,它的作用与您想要的相反。以下命令将列出远程分支上本地没有的所有标记:

git ls-remote --tags origin | git show-ref --tags --exclude-existing

刚刚在GitHub上的pivotal_git_scripts Gem fork中添加了一个git sync local tags命令:

安装gem,然后在存储库中运行git sync local tags以删除远程服务器上不存在的本地标记

或者,您可以在下面安装此脚本并将其称为git sync local tags:


这是一个很好的问题,我一直在想同样的事情

我不想写剧本,所以我寻求了一个不同的解决方案。关键是发现您可以在本地删除标记,然后使用git fetch从远程服务器取回它。如果远程设备上不存在该标记,则该标记仍将被删除

因此,您需要按顺序键入两行:

git tag -l | xargs git tag -d
git fetch --tags
这些:

从本地回购中删除所有标签。FWIW、xargs将tag-l输出的每个标记放在tag-d的命令行上。没有这个,git不会删除任何内容,因为它不读取StdinGit

从远程repo获取所有活动标记


这甚至可以在Windows上使用。

从Git v1.7.8到v1.8.5.6,您可以使用:

git fetch <remote> --prune --tags
使现代化 这在从v1.9.0开始的较新版本的git上不起作用,因为存在提交问题。但我并不真的想删除它,因为它确实对某些人有用

正如Chad Juliano所建议的,对于自v1.7.8以来的所有Git版本,您可以使用以下命令:

git fetch --prune <remote> +refs/tags/*:refs/tags/*
您可能需要在Windows上用引号括起标记部件,例如,以避免通配符扩展:

git fetch --prune <remote> "+refs/tags/*:refs/tags/*"

这样如何-删除所有本地标记,然后重新获取? 考虑到您的回购协议可能包含子模块:

git submodule foreach --recursive  'git tag | xargs git tag -d'
(alternatively, "for i in `find .git  -type d -name '*tags*'`; do rm -f $i/*;  done")
git fetch -t
git submodule foreach --recursive git fetch -t

如果您只需要远程设备上存在的标记,只需删除所有本地标记:

$ git tag -d $(git tag)
然后获取所有远程标记:

$ git fetch --tags
diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)

显示本地标记和远程标记之间的差异:

$ git fetch --tags
diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)
git标记提供本地标记的列表 gitlsremote-tags提供远程标记的完整路径列表 cut-f2 | grep-v'\^'| sed'srefs/tags/'只解析远程标记路径列表中的标记名 最后,我们对这两个列表进行排序并进行区分
以<开头的行是您的本地标记,它们不再位于远程回购中。如果它们很少,您可以逐个手动删除它们,如果它们很多,您可以执行更多的grep-ing和piping来实现自动化。

自1.7.8版以来的所有Git版本都使用refspec来理解Git fetch,而自1.9.0版以来,-tags选项覆盖了-prune选项。对于通用解决方案,请尝试以下方法:

$ git --version
git version 2.1.3

$ git fetch --prune origin "+refs/tags/*:refs/tags/*"
From ssh://xxx
 x [deleted]         (none)     -> rel_test

要进一步了解Git v1.9.0中带-prune行为的-tags是如何改变的,请参阅:

TortoiseGit现在可以比较标记了

左日志位于远程,右日志位于本地

使用同步对话框的比较标记功能:

另请参见

这是一种很好的方法:

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


来源:

Git本机支持清除本地标记

git fetch --tags --prune-tags

这个命令拉入最新的标记并删除所有已删除的标记

看起来像是最新版本的Git I'm on Git v2.20

git fetch-prune-prune标记 干净多了

您还可以将git配置为在获取时始终修剪标记:

git config fetch.pruetags true 如果只希望在从特定远程设备获取时修剪标记,则可以使用remote..pruneTags选项。例如,要在从源站(而不是其他远程站)获取时始终修剪标记

git config remote.origin.pruneTags true
答案与@Richard W相同,但适用于Windows PowerShell

git tag | foreach-object -process { git tag -d $_ }
git fetch -t
更新日期:2021/05 将$REPO参数传递给自定义脚本

sync_git_tags.sh的内容

古老的 < p> ps:2021/05更新,git fetch-prune-prune标记源代码在我的MacOS中不起作用

我将该命令作为MacOS上的自定义操作添加到SourceTree。 按Sourcetree->Preferences设置自定义操作…->自定义操作

`要运行的脚本必须是git路径。 我使用git fetch-prune-prune标记源将标记从远程同步到本地


我知道我来晚了,但现在有一个快速的答案:

git fetch --prune --prune-tags # or just git fetch -p -P
是的,它现在是一个获取的选项

如果不想提取,只需修剪:

git remote prune origin

在新的git版本(如v2.26.2)中

-P、 -删除标签 在获取之前,如果启用了-prune,请删除远程服务器上不再存在的任何本地标记。应该更仔细地使用这个选项,不像-prune,它将删除任何本地引用本地标记 已经创建了。此选项是提供显式标记refspec和-prune的简写,请参见其文档中的讨论

因此,您需要运行:

git fetch origin --prune --prune-tags


谢谢你,迈克。我将使用每个列表滚动我自己的bash脚本进行比较。Richard W的回答更优雅地做到了这一点,如果您对一个复杂的脚本不感兴趣,可以扩展关于本地不存在的标记的旁注,以检查更多的远程:git remote | xargs-L 1 git ls remote-tags | git show ref-tags-排除现有的git支持-prune标记。不确定引入了什么版本。我在git中提出了一个新特性来支持修剪过时的标记:注意:对于git 2.17 2018年第二季度,一个简单的git config fetch.pruetags true将使您的git fetch实现您想要的功能!请参阅。重新发布以下答案之一的评论:至少在git 2.18.0中,还可以使用以下语法:git fetch-prune-prune tags originThank@zutnop。对于今天的git版本,我几乎错过了正确的答案。这一定是我在StackOverflow上最喜欢的git答案。它结合了知识、简单和诡计,解释了一切。Greatas在一个单独的回答中指出,这将删除所有本地标记,而不在远程repo中的标记显然不会被重新创建,这应该是完全不必要的。应该有一个git-tag-prune-origin命令。这可能不适合所有人。为了安全起见,您应该使用git fetch-tags。我必须使用git-tag-l |%{git-tag-d$}才能在PowerShell中工作。我不确定是否还有其他人。我参考了与Git for Windows 1.9.4-preview20140611一起打包的文档,我怀疑所有以前的版本。我使用git fetch-help[quote]标记访问上述文档,如果仅因为默认标记自动跟随或由于-Tags选项而获取这些标记,则不会对其进行修剪。[/quote]git fetch-prune+refs/tags/*:refs/tags/*在ZSH中不起作用,但在BASH@Alex这仅仅是因为zsh扩展了*但是如果你用单引号引用,它应该是好的。@v01pe-现在有一个git快捷方式-prune标记可用,因为git 2.17.0在文档的“剪枝”部分中有描述:来自文档:剪枝标记选项相当于在远程服务器的refspec中声明refs/tags/*:refs/tags/*。等价物:git-fetch-origin-prune-prune标记或git-fetch-origin-prune“refs/tags/*:refs/tags/*”或git-fetch-prune-prune标记或git-fetch-prune“refs/tags/*:refs/tags/*”git-fetch-origin-prune标记修剪远程跟踪分支和标记。在Git 2.18版本中检查。请考虑添加一些解释到您的代码。这将明显提高您的答案的质量。删除本地不存在的所有远程标记的完整命令将是:diff如果您需要这样一个diff并同时显示提交哈希:diff这个比较正是我想要的,谢谢。我唯一感到困惑的是,它还输出了几行不是以箭头@ocroquette开头的行,我不确定它比xargs好多少。如果您有比ARG_MAX更多的标记,或者有类似的限制,这将不起作用。不太可能,但可能,这就是为什么xargs很棒。好是一件主观的事情,每个人都会有自己的看法。关于ARG_MAX,这是真的。但是,在我使用的系统上,ARG_MAX远远高于我在任何存储库中的标记数量,因此我不介意限制,正如我在编写ls*.jpg.cleansest solutiongit config-global alias.prune-tags'时不介意限制一样!git-tag-d$git-tag&&git-fetch-tags的强制别名命令。享受-谢谢,一个简单的问题有很多复杂的答案,这应该是最重要的答案。这是一个单一的git命令,没有bash、管道和xargs;下一个git push origin:更新了my GitHub fork,删除了已删除的标记。至少在git 2.18.0中,还可以使用以下语法:git fetch-prune-prune tags originStarting with git 2.17.0-the-prune tags选项包括在内,并在“修剪”一节中用
以下文档中的等效命令:git fetch origin-prune-prune标记或git fetch origin-prune'refs/tags/*:refs/tags/*'或git fetch-prune-prune标记或git fetch-prune'refs/tags/*:refs/tags/*'看起来应该是-prune而不是-prune标记,否则这就是我需要的,谢谢。我在源代码树中遇到问题,无法将某些引用推送到…:这对我有用:谢谢Alot@AnyDev:-删除标记是正确的。手册页上写着关于-prune:如果标签只是因为默认的标签自动跟随或者由于-Tags选项而被获取,那么标签就不会被修剪。很好。我已经把它改贴在国企->上了。太好了!我遇到git推送失败,git shell死于信号13。即使增加了http.postbuffer,也没有效果。在启用GIT_TRACE_数据包和GIT_TRACE之后,我看到推送无效的refs/tags,所以使用-prune tags来解决它。谢谢!可以写为git fetch-ppp谢谢!现在这应该是正确的答案。