如何推送所有带注释的标签?

How to push all annotated tags?

如何在不推送轻量级标签的情况下将所有带注释的标签从我的本地存储库推送到远程?

我在本地使用不想推送的轻量级标签,因此 git push --tags 不是解决方案。

我知道 git push --follow-tags 但它只会推送与当前推送的提交关联的标签。

我需要这个选项,因为我的正常工作流程不时涉及推送,但只有在完成发布时才添加标签,而且我有时会忘记推送标签。这个问题通常很长一段时间都不会被发现,并且会导致其他开发人员有点困惑,因为我们与我们的标签不同步。

由于列出哪些annotated标签存在于本地而不是远程很复杂,我想通过推送所有本地注释标签来解决这个问题,这将确保所有开发人员' 本地和远程存储库具有相同的注释标签。

不是太难。首先找到所有 annotated 标签(通过拒绝直接指向提交而不是带注释的标签对象的标签)。这有点长,所以您可能希望将其写成 shell 函数:

list_annotated_tags() {
    git for-each-ref --format '%(objecttype) %(refname)' refs/tags |
        while read reftype refname; do
            case $reftype in tag) echo $refname;; esac
        done
}

阅读上面的输出并将它们用作 git push 命令的 refspec 参数:

git push origin $(list_annotated_tags)

您的脚本已完成。

我注意到我的轻量级标签不包含 taggerdate。在这种情况下,这将在命令行或脚本中起作用:

taglist=`git for-each-ref refs/tags --format '%(refname:short) %09 %(taggerdate:short)' | \
grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2}' | \
cut -f 1 | \
tr '\n' ' '`

其次是:

git push origin $taglist

命令总结,给有兴趣的人:

  • 第 1 行 - 检索 git for-each-ref 标签列表,格式化为显示标签名、标签和日期。 (只有带注释的标签才会有日期。)
  • 第 2 行 - grep 命令搜索第一个命令的结果,仅提取带有日期的标签。
  • 第 3 行 - cut 命令删除初始列之后的所有内容(即,从每个标记名后面的制表符之前到每个结果行结束的 newline)。
  • 第 4 行 - tr 命令在最终结果中将 newline 替换为 space。 (标记名现在在一行上,用 space 分隔。)

结果存储在一个变量中(taglist - 请注意 taglist= 之后整个命令集开头和结尾的反引号)。

最后,然后,将标签列表推送到 origin(使用 $ 表示 taglist 是一个变量)。