【问题标题】:list tags contained by a branch列出分支包含的标签
【发布时间】:2010-03-04 18:20:30
【问题描述】:

如何列出给定分支包含的标签,与以下相反:

git tag --contains <commit>

其中“仅列出包含指定提交的标签”。

如果这样的东西不存在,我如何测试一个提交是否包含在另一个提交中,以便我可以编写这个脚本?

我可以这样做:

commit=$(git rev-parse $branch)
for tag in $(git tag)
do
    git log --pretty=%H $tag | grep -q -E "^$commit$"
done

但我希望有更好的方法,因为这可能需要很长时间在具有许多标签和提交的存储库中。

【问题讨论】:

标签: git


【解决方案1】:
git tag --merged <branch>

来自手册页:

--[no-]merged <commit>

Only list tags whose tips are reachable, or not reachable if --no-merged is used, from the specified commit (HEAD if not specified).

我相信这个选项是最近才添加的 - 当提出原始问题并建议上述答案时,它肯定不可用。由于这个线程仍然是谷歌的第一个问题,我想我会把它扔给任何向下滚动到底部以寻找比接受的答案更少打字的答案的人(当我忘记时供我自己参考下周再回答这个问题)。

【讨论】:

  • 于 2015 年 9 月添加,it seems。现在应该是 IMO 接受的答案。
  • 同意,这正是我想要的。
  • 在一个分支中列出标签而不是另一个标签也是可能的:git tag --merged debian --no-merged upstream(当一个分支合并到另一个分支时很有用)
  • @FranklinPiat:“错误:选项 `no-merged' 与 --merged 不兼容”
  • @FranklinPiat - 我认为这也有效,但根据这个错误报告,它实际上完全放弃了第一个选项:github.com/git/git/commit/…
【解决方案2】:

这可能接近你想要的:

git log --simplify-by-decoration --decorate --pretty=oneline "$committish" | fgrep 'tag: '

但是,更常见的情况是只找到最近的标签:

git describe --tags --abbrev=0 "$committish"
  • --tags 将搜索轻量级标签,如果您只想考虑带注释的标签,请不要使用它。
  • 如果您还想查看通常的“‘顶部提交数’和缩写哈希”后缀(例如 v1.7.0-17-g7e5eb8),请勿使用 --abbrev=0

【讨论】:

  • 从 Git 1.7.10 开始,它不起作用 --pretty=format:%d 列出 refs 而没有说明它是标签还是分支
  • @CharlesB:编辑更改为log。我没有正确地将它一分为二,但看起来变化(回归?)可能已经发生在 1.7.2 中:a7524128 更改了内部装饰文本,但只调整了其中一个格式化函数来补偿(log-tree. c:show_decoration 已调整,而 pretty.c:format_decoration 受到(意外?)更改的影响。
  • 对我来说,这给出了:致命:不明确的参数'':未知修订或路径不在工作树中。使用 '--' 将路径与修订分开(git 版本 1.7.9.5)
  • @rooby:该错误消息表明您在命令中的某处包含了一个空字符串。您是否替换了您正在调查的提交/分支/标签的哈希字符串(即我使用占位符 $committish 的位置)?
  • 这实际上并没有回答它只是显示最新标签的问题......而不是“标签”(复数)“包含在一个分支”
【解决方案3】:

列出当前分支上所有可达的标签:

git log --decorate=full --simplify-by-decoration --pretty=oneline HEAD | \
sed -r -e 's#^[^\(]*\(([^\)]*)\).*$#\1#' \
       -e 's#,#\n#g' | \
grep 'tag:' | \
sed -r -e 's#[[:space:]]*tag:[[:space:]]*##'

【讨论】:

  • 在 OS X 上将 sed -r 替换为 sed -E
  • git log --decorate=full --simplify-by-decoration --pretty=oneline HEAD 的格式在编辑此答案后发生了一些变化
  • git log --decorate --oneline | egrep '^[0-9a-f]+ \(tag: ' | sed -r 's/^.+tag: ([^ ]+)[,\)].+$/\1/g'
  • shkschneider 的评论在最新提交时不包含标签。
【解决方案4】:

我没有足够的声誉来评论其他人的帖子,但这是对https://stackoverflow.com/a/7698213/2598329 的答案及其cmets 的回应。为了显示当前分支可访问的所有标签,包括 HEAD 提交上的标签,您可以使用以下内容:

git log --decorate --oneline | egrep '^[0-9a-f]+ \((HEAD, )?tag: ' | ssed -r 's/^.+tag: ([^ ]+)[,\)].+$/\1/g'

一个警告 - 我使用超级 sed,因此您可能需要将我的“ssed”更改为 sed。

最重要的是,它在 PowerShell 中:

git log --decorate --oneline | % { if ($_ -match "^[0-9a-f]+ \((HEAD, )?tag: ") { echo $_} } | % { $_ -replace "^.+tag: ([^ ]+)[,\)].+$", "`$1" }

-- -a

【讨论】:

  • 您是否有理由不只是将答案更改为使用 sed 而不是 ssed,因为这更有可能是其他用户所拥有的?
  • 我同意,但应该注意的是,在 os x 上,默认的 sed 没有 -r 选项。需要通过自制软件切换到gnu-sed... 或其他方式。
【解决方案5】:

你可以用这个:

# get tags on the last 100 commits:
base_rev=master~100
end_rev=master
for rev in $(git rev-list $base_rev..$end_rev)
do 
    git describe --exact-match $rev 2> /dev/null
done

【讨论】:

  • 这只适用于你的 repo 有 >100 次提交并且你需要的标签是 >100 次之前的提交,那么你就不走运了。
【解决方案6】:

以下是我按时间倒序列出与模式 (TAG_PREFIX*) 匹配的带注释标签的方法。本食谱使用 git-describe。

#!/usr/bin/env bash

tag=$(git describe --abbrev=0 --match TAG_PREFIX*)
until [ -z $tag ]; do
    echo $tag
    tag=$(git describe --abbrev=0 --match TAG_PREFIX* $tag^ 2>/dev/null);
done

如果匹配模式的多个标签指向同一个提交,这将不起作用。为此,这里有另一个配方,它使用 git-rev-list 和 git-tag 列出所有标签,匹配 TAG_PREFIX*,从提交开始(本例中为 HEAD)。

#!/usr/bin/env bash

git rev-list HEAD | while read sha1; do
    tags=( "$(git tag -l --points-at $sha1 TAG_PREFIX*)" )
    [[ ! -z ${tags[*]} ]] && echo "${tags[@]}" | sort -r
done

【讨论】:

    【解决方案7】:

    all answer only list tags,但如果要按时间顺序排列,需要加--sort=taggerdate

    或示例:

     git tag --merged release/11.x --sort=taggerdate
    studio-1.4
    llvmorg-10-init
    llvmorg-11-init
    llvmorg-11.0.0-rc1
    llvmorg-11.0.0-rc2
    llvmorg-11.0.0-rc3
    llvmorg-11.0.0-rc4
    llvmorg-11.0.0-rc5
    llvmorg-11.0.0-rc6
    llvmorg-11.0.0
    

    【讨论】:

      【解决方案8】:

      适用于任何人的 Windows 特定答案。

      Powershell 最近已经开源和跨平台,所以下面给出的命令也可以在 Windows 以外的系统上运行。

      注意:以下适用于旧版本的 git 或特定用例!

      对于 powershell:

      git log --simplify-by-decoration --decorate --pretty=oneline "$committish" | Select-String 'tag: '
      

      您还可以使用:-CaseSensitive 标志用于 Select-String 以使其区分大小写

      对于 cmd:

      git log --simplify-by-decoration --decorate --pretty=oneline | findstr -i "tag: "
      

      您可以删除 -i 以使搜索区分大小写

      注意:对于较新的版本和跨平台,只要它支持 git 命令就可以跨终端:

      git tag --merged <branchname>
      

      您可以使用格式、颜色、排序和许多其他选项。在这里查看所有内容:https://git-scm.com/docs/git-tag

      【讨论】:

        【解决方案9】:

        高效处理大量标签并获得轻松的格式灵活性:

        { git rev-list --first-parent ${1:-HEAD}
          git for-each-ref --format='%(objectname) %(objecttype)  %(refname)
                                     %(*objectname) *(%(objecttype)) %(refname)' 
        } \
        | awk '
          NF==1   { revs[$1]=1; next }
                  { if ( $1 in revs ) print $1,$2,$3 }
        '
        

        获取所有 refs,将 refs/tags 添加到 f-e-r 以限制它。

        【讨论】:

          【解决方案10】:

          git describe(或它的一些变体)可能是您正在寻找的。​​p>

          【讨论】:

          • 不,git describe 只会列出一个标签/参考。
          【解决方案11】:

          有一个git branch --contains(至少从 1.5.7 开始的 Git)

          【讨论】:

          • 这甚至不能远程执行所要求的操作。 “使用--contains,仅显示包含命名提交的分支”......他没有要求包含提交的分支。他在一个分支中要求标签。
          猜你喜欢
          • 2013-06-17
          • 1970-01-01
          • 2013-04-24
          • 2010-11-28
          • 1970-01-01
          • 2011-12-16
          • 2018-11-27
          • 2012-07-04
          相关资源
          最近更新 更多