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

发布于 2024-08-12 23:18:38 字数 287 浏览 2 评论 0原文

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

这非常简单。一个用户通过一组命令删除本地标签和远程标签。我们有一个结合了这两个步骤的小 shell 脚本。

第二个(第三个、第四个……)用户现在拥有不再反映在远程上的本地标签。

我正在寻找类似于 git Remote prune origin 的命令,该命令可以清理已删除远程分支的本地跟踪分支。

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

We use tags in git as part of our deployment process. From time to time, we want to clean up these tags by removing them from our remote repository.

This is pretty straightforward. One user deletes the local tag and the remote tag in one set of commands. We have a little shell script that combines both steps.

The 2nd (3rd, 4th,...) user now has local tags that are no longer reflected on the remote.

I am looking for a command similar to git remote prune origin which cleans up locally tracking branches for which the remote branch has been deleted.

Alternatively, a simple command to list remote tags could be used to compare to the local tags returned via git tag -l.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

高跟鞋的旋律 2024-08-19 23:18:38

这是一个很好的问题,我也一直想知道同样的事情。

我不想编写脚本,因此寻求不同的解决方案。关键是发现您可以在本地删除标签,然后使用 git fetch 从远程服务器“取回”它。如果遥控器上不存在该标签,则它将保持删除状态。

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

git tag -l | xargs git tag -d
git fetch --tags

这些:

  1. 从本地存储库中删除所有标签。 FWIW,xargs 将“tag -l”输出的每个标签放置到“tag -d”的命令行上。如果没有这个,git 将不会删除任何内容,因为它不读取标准输入(愚蠢的 git)。

  2. 从远程存储库中获取所有活动标签。

这甚至在 Windows 上也能发挥作用。

This is great question, I'd been wondering the same thing.

I didn't want to write a script so sought a different solution. The key is discovering that you can delete a tag locally, then use git fetch to "get it back" from the remote server. If the tag doesn't exist on the remote, then it will remain deleted.

Thus you need to type two lines in order:

git tag -l | xargs git tag -d
git fetch --tags

These:

  1. Delete all tags from the local repo. FWIW, xargs places each tag output by "tag -l" onto the command line for "tag -d". Without this, git won't delete anything because it doesn't read stdin (silly git).

  2. Fetch all active tags from the remote repo.

This even works a treat on Windows.

白衬杉格子梦 2024-08-19 23:18:38

看起来最近版本的 Git(我使用的是 git v2.20)可以让人们简单地说“

git fetch --prune --prune-tags

干净得多”!

https://git-scm.com/docs/git-fetch#_pruning

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

git config fetch.pruneTags true

如果您只想在从特定远程获取时修剪标签,则可以使用 remote..pruneTags 选项。例如,在从源而不是其他远程获取时始终修剪标签,

git config remote.origin.pruneTags true

Looks like recentish versions of Git (I'm on git v2.20) allow one to simply say

git fetch --prune --prune-tags

Much cleaner!

https://git-scm.com/docs/git-fetch#_pruning

You can also configure git to always prune tags when fetching:

git config fetch.pruneTags true

If you only want to prune tags when fetching from a specific remote, you can use the remote.<remote>.pruneTags option. For example, to always prune tags when fetching from origin but not other remotes,

git config remote.origin.pruneTags true
梦醒灬来后我 2024-08-19 23:18:38

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

git fetch <remote> --prune --tags

更新

这不适用于较新版本的 git(从 v1.9.0 开始),因为提交 e66ef7ae6f31f2。我真的不想删除它,因为它确实对某些人有用。

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

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

您可能需要用引号将标签部分括起来(例如在 Windows 上)以避免通配符扩展:

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

注意:在所有这些中案例可能是“来源”或您通常引用的任何遥控器。

From Git v1.7.8 to v1.8.5.6, you can use this:

git fetch <remote> --prune --tags

Update

This doesn't work on newer versions of git (starting with v1.9.0) because of commit e66ef7ae6f31f2. I don't really want to delete it though since it did work for some people.

As suggested by "Chad Juliano", with all Git version since v1.7.8, you can use the following command:

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

You may need to enclose the tags part with quotes (on Windows for example) to avoid wildcard expansion:

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

NOTE: in all these cases would be likely be "origin" or whichever remote you might usually reference.

橘虞初梦 2024-08-19 23:18:38

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

$ git tag -d $(git tag)

然后获取所有远程标签:

$ git fetch --tags

If you only want those tags which exist on the remote, simply delete all your local tags:

$ git tag -d $(git tag)

And then fetch all the remote tags:

$ git fetch --tags
一桥轻雨一伞开 2024-08-19 23:18:38

自 v1.7.8 起,所有版本的 Git 都可以使用 refspec 来理解 git fetch,而自 v1.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 中“--tags”和“--prune”行为如何更改,请参阅:https://github.com/git/git/commit/e66ef7ae6f31f246dead62f574cc2acb75fd001c

All versions of Git since v1.7.8 understand git fetch with a refspec, whereas since v1.9.0 the --tags option overrides the --prune option. For a general purpose solution, try this:

$ git --version
git version 2.1.3

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

For further reading on how the "--tags" with "--prune" behavior changed in Git v1.9.0, see: https://github.com/git/git/commit/e66ef7ae6f31f246dead62f574cc2acb75fd001c

甜妞爱困 2024-08-19 23:18:38

好问题。 :) 我没有完整的答案...

也就是说,您可以通过 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 脚本来比较由此列表包含您本地拥有的标签。看一下 git show-ref --tags,它生成的标签名称与 git ls-remote 的形式相同。


顺便说一句, git show-ref 有一个选项与您想要的相反。以下命令将列出远程分支上您本地没有的所有标签:

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

Good question. :) I don't have a complete answer...

That said, you can get a list of remote tags via git ls-remote. To list the tags in the repository referenced by origin, you'd run:

git ls-remote --tags origin

That returns a list of hashes and friendly tag names, like:

94bf6de8315d9a7b22385e86e1f5add9183bcb3c        refs/tags/v0.1.3
cc047da6604bdd9a0e5ecbba3375ba6f09eed09d        refs/tags/v0.1.4
...
2f2e45bedf67dedb8d1dc0d02612345ee5c893f2        refs/tags/v0.5.4

You could certainly put together a bash script to compare the tags generated by this list with the tags you have locally. Take a look at git show-ref --tags, which generates the tag names in the same form as git ls-remote).


As an aside, git show-ref has an option that does the opposite of what you'd like. The following command would list all the tags on the remote branch that you don't have locally:

git ls-remote --tags origin | git show-ref --tags --exclude-existing
潜移默化 2024-08-19 23:18:38

在新的 git 版本(如 v2.26.2 或更高版本)中,您可以使用 --prune-tags

-P
--修剪标签
如果启用了 --prune,则在获取之前,请删除远程上不再存在的所有本地标签。应更谨慎地使用此选项,与 --prune 不同,它会删除已创建的任何本地引用(本地标记)。此选项是与 --prune 一起提供显式标记 refspec 的简写,请参阅其文档中对此的讨论。

所以你需要运行:

git fetch origin --prune --prune-tags

In new git versions (like v2.26.2 or higher) you could use --prune-tags

-P
--prune-tags
Before fetching, remove any local tags that no longer exist on the remote if --prune is enabled. This option should be used more carefully, unlike --prune it will remove any local references (local tags) that have been created. This option is a shorthand for providing the explicit tag refspec along with --prune, see the discussion about that in its documentation.

So you would need to run:

git fetch origin --prune --prune-tags
扮仙女 2024-08-19 23:18:38

Git 原生支持本地标签的清理

git fetch --tags --prune-tags

该命令拉入最新的标签并删除所有已删除的标签

Git natively supports cleanup of local tags

git fetch --tags --prune-tags

This command pulls in the latest tags and removes all deleted tags

带上头具痛哭 2024-08-19 23:18:38

我知道我参加聚会迟到了,但现在有一个快速答案:

git fetch --prune --prune-tags # or just git fetch -p -P

是的,现在是一个获取选项。

如果您不想获取,只需修剪:

git remote prune origin

I know I'm late to the party, but now there's a quick answer to this:

git fetch --prune --prune-tags # or just git fetch -p -P

Yes, it's now an option to fetch.

If you don't want to fetch, and just prune:

git remote prune origin
︶ ̄淡然 2024-08-19 23:18:38

这是一个好方法:

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

来源:demisx.GitHub.io

this is a good method:

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

Source: demisx.GitHub.io

◇流星雨 2024-08-19 23:18:38

与 @Richard W 的答案相同,但适用于 Windows (PowerShell)

git tag | ForEach-Object -Process { git tag -d $_ }
git fetch -t

The same answer as @Richard W but for Windows (PowerShell)

git tag | ForEach-Object -Process { git tag -d $_ }
git fetch -t
笨死的猪 2024-08-19 23:18:38

更新@2021/05

在此处输入图像描述

$REPO 参数传递给自定义脚本。

sync_git_tags.sh 的内容

#!/bin/sh

# cd to $REPO directory
cd $1
pwd

# sync remote tags
git tag -l | xargs git tag -d && git fetch -t

ps:更新于@2021/05,git fetch --prune --prune-tags origin 在我的 MacOS 中不起作用。

我将该命令作为 MacOS 上的自定义操作添加到 SourceTree 中。

通过 Sourcetree 设置自定义操作 -> 首选项... -> 自定义操作

`Script to run` have to be the `git` path.

我使用git fetch --prune --prune-tags origin 将标签从远程同步到本地。

输入图片此处描述
输入图片此处描述

Updated @2021/05

enter image description here

Pass $REPO parameter to custom script.

The content of sync_git_tags.sh

#!/bin/sh

# cd to $REPO directory
cd $1
pwd

# sync remote tags
git tag -l | xargs git tag -d && git fetch -t

Old

ps: updated @2021/05, git fetch --prune --prune-tags origin not working in my MacOS.

I add the command to SourceTree as a Custom Action on my MacOS.

Setting Custom Actions by Sourcetree -> Preferences... -> Custom Actions

`Script to run` have to be the `git` path.

I use git fetch --prune --prune-tags origin to sync tags from remote to local.

enter image description here
enter image description here

终遇你 2024-08-19 23:18:38

显示本地标签和远程标签之间的区别:

diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)
  • git tag 给出本地标签的列表
  • git ls-remote --tags 给出远程标签的完整路径列表
  • 切-f2 | grep -v '\^' | grep -v '\^' | sed 's#refs/tags/##' 从远程标记路径列表中解析出标记名称
  • 最后,我们对两个列表中的每一个进行排序并比较它们

以“<”开头的行是您的本地标记不再在远程仓库中。如果它们很少,您可以手动将它们一一删除,如果它们很多,您可以执行更多的 grep 和管道来自动化它。

Show the difference between local and remote tags:

diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)
  • git tag gives the list of local tags
  • git ls-remote --tags gives the list of full paths to remote tags
  • cut -f2 | grep -v '\^' | sed 's#refs/tags/##' parses out just the tag name from list of remote tag paths
  • Finally we sort each of the two lists and diff them

The lines starting with "< " are your local tags that are no longer in the remote repo. If they are few, you can remove them manually one by one, if they are many, you do more grep-ing and piping to automate it.

初与友歌 2024-08-19 23:18:38

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

https://github.com/kigster/ git_scripts

安装 gem,然后在存储库中运行“gitsync-local-tags”以删除远程上不存在的本地标签。

或者,您可以安装下面的脚本并将其命名为“git-sync-local-tags”:


#!/usr/bin/env ruby

# Delete tags from the local Git repository, which are not found on 
# a remote origin
#
# Usage: git sync-local-tags [-n]
#        if -n is passed, just print the tag to be deleted, but do not 
#        actually delete it.
#
# Author: Konstantin Gredeskoul (http://tektastic.com)
#
#######################################################################

class TagSynchronizer
  def self.local_tags
    `git show-ref --tags | awk '{print $2}'`.split(/\n/)
  end

  def self.remote_tags
    `git ls-remote --tags origin | awk '{print $2}'`.split(/\n/)
  end

  def self.orphaned_tags
    self.local_tags - self.remote_tags
  end

  def self.remove_unused_tags(print_only = false)
    self.orphaned_tags.each do |ref|
      tag = ref.gsub /refs\/tags\//, ''
      puts "deleting local tag #{tag}"
      `git tag -d #{tag}` unless print_only
    end
  end
end

unless File.exists?(".git")
  puts "This doesn't look like a git repository."
  exit 1
end

print_only = ARGV.include?("-n")
TagSynchronizer.remove_unused_tags(print_only)

Just added a git sync-local-tags command to pivotal_git_scripts Gem fork on GitHub:

https://github.com/kigster/git_scripts

Install the gem, then run "git sync-local-tags" in your repository to delete the local tags that do not exist on the remote.

Alternatively you can just install this script below and call it "git-sync-local-tags":


#!/usr/bin/env ruby

# Delete tags from the local Git repository, which are not found on 
# a remote origin
#
# Usage: git sync-local-tags [-n]
#        if -n is passed, just print the tag to be deleted, but do not 
#        actually delete it.
#
# Author: Konstantin Gredeskoul (http://tektastic.com)
#
#######################################################################

class TagSynchronizer
  def self.local_tags
    `git show-ref --tags | awk '{print $2}'`.split(/\n/)
  end

  def self.remote_tags
    `git ls-remote --tags origin | awk '{print $2}'`.split(/\n/)
  end

  def self.orphaned_tags
    self.local_tags - self.remote_tags
  end

  def self.remove_unused_tags(print_only = false)
    self.orphaned_tags.each do |ref|
      tag = ref.gsub /refs\/tags\//, ''
      puts "deleting local tag #{tag}"
      `git tag -d #{tag}` unless print_only
    end
  end
end

unless File.exists?(".git")
  puts "This doesn't look like a git repository."
  exit 1
end

print_only = ARGV.include?("-n")
TagSynchronizer.remove_unused_tags(print_only)
花开浅夏 2024-08-19 23:18:38

怎么样 - 删除所有本地标签然后重新获取?
考虑到您的存储库可能包含子模块:

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

How about this - drop all local tags and then re-fetch?
Considering your repo might contain submodules:

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
七色彩虹 2024-08-19 23:18:38

TortoiseGit 现在可以比较标签了。

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

输入图片此处说明

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

在此处输入图像描述

另请参阅 TortoiseGit 问题 2973

TortoiseGit can compare tags now.

Left log is on remote, right is at local.

enter image description here

Using the Compare tags feature of Sync dialog:

enter image description here

Also see TortoiseGit issue 2973

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文