删除远程存储库中不再存在的本地 git 标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1841341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:27:57  来源:igfitidea点击:

Remove local git tags that are no longer on the remote repository

gitgit-tag

提问by kEND

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.

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

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.

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

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

第 2 个(第 3 个、第 4 个……)用户现在具有不再反映在遥控器上的本地标签。

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

我正在寻找类似于git remote prune origin清除远程分支已删除的本地跟踪分支的命令。

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

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

采纳答案by Mike West

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. 要列出由 引用的存储库中的标签origin,您需要运行:

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).

您当然可以组合一个 bash 脚本来比较此列表生成的标签与您在本地拥有的标签。看看git show-ref --tags,它以与 相同的形式生成标签名称git ls-remote)。



As an aside, git show-refhas 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'thave locally:

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

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

回答by Richard W

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.

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

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.

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

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

This even works a treat on Windows.

这甚至适用于 Windows。

回答by loganfsmyth

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

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

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.

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

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

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

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:

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

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

回答by newmangt

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

回答by Nicholas Carey

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

看起来最近版本的 Git(我在 git v2.20 上)允许人们简单地说

git fetch --prune --prune-tags

Much cleaner!

干净多了!

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

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

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

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

git config fetch.pruneTags true

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

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

git config remote.origin.pruneTags true

回答by Chad Juliano

All versions of Git since v1.7.8 understand git fetchwith a refspec, whereas since v1.9.0 the --tagsoption overrides the --pruneoption. For a general purpose solution, try this:

git fetch自 v1.7.8以来的所有 Git 版本都使用 refspec 来理解,而自 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

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

如需进一步了解 Git v1.9.0 中“--tags”和“--prune”行为如何变化,请参阅:https: //github.com/git/git/commit/e66ef7ae6f31f246dead62f574cc2acb75fd001c

回答by Nirav Shah

Git natively supports cleanup of local tags:

Git 本身支持清理本地标签:

git fetch --tags --prune

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

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

回答by imjoseangel

this is a good method:

这是一个很好的方法:

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

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

Source: demisx.GitHub.io

来源:demisx.GitHub.io

回答by dotstaraj

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 taggives the list of local tags
  • git ls-remote --tagsgives 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
  • git tag给出本地标签列表
  • git ls-remote --tags给出远程标签的完整路径列表
  • cut -f2 | grep -v '\^' | sed 's#refs/tags/##'仅从远程标签路径列表中解析出标签名称
  • 最后,我们对两个列表中的每一个进行排序并比较它们

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.

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

回答by Konstantin Gredeskoul

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

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

https://github.com/kigster/git_scripts

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.

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

Alternatively you can just install this script below and call it "git-sync-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 }'`.split(/\n/)
  end

  def self.remote_tags
    `git ls-remote --tags origin | awk '{print }'`.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)