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

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

第二个(第3个,第4个,……)用户现在拥有不再反映在远程上的本地标记。

我正在寻找一个类似于git远程修剪起源的命令,清理本地跟踪分支,其中远程分支已被删除。

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


当前回答

这是个好问题,我也一直在想同样的问题。

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

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

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

这些:

从本地回收中删除所有标签。总之,xargs将每个通过“tag -l”输出的标记放到“tag -d”的命令行上。没有这个,git不会删除任何东西,因为它不读取stdin(愚蠢的git)。 从远程回收中获取所有活动标记。

这甚至在Windows上也很有效。

其他回答

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

有关“——tags”和“——prune”行为在Git v1.9.0中如何改变的进一步阅读,请参见:https://github.com/git/git/commit/e66ef7ae6f31f246dead62f574cc2acb75fd001c

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

https://github.com/kigster/git_scripts

安装gem,然后在存储库中运行"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 $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)

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

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

标记给出了本地标记的列表 Git ls-remote——tags给出了远程标记的完整路径列表 Cut -f2 | grep -v '\^' | sed 's#refs/tags/##'只从远程标签路径列表中解析出标签名 最后,我们对这两个表分别进行排序和区分

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

TortoiseGit现在可以比较标签了。

左边是远程日志,右边是本地日志。

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

另见TortoiseGit 2973期

这是一个很好的方法:

Git标签-l | xargs Git标签-d && Git获取-t

来源:demisx.GitHub.io