分支所包含的列表标记

如何列出给定分支包含的标记,而不是:

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

但是我希望有更好的方法,因为在存储库中使用许多标记和提交可能会花费很长时间。

93963 次浏览

Git description (或者它的一些变体)可能就是您要找的。

这可能接近你想要的:

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

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

git describe --tags --abbrev=0 "$committish"
  • --tags将针对轻量级标记进行搜索,如果您只想考虑带注释的标记,则不要使用它。
  • 不要使用 --abbrev=0,如果你还想看到通常的“数字‘提交在上面’和缩写散列”后缀(例如 v1.7.0-17-g7e5eb8)。

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

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:]]*##'

你可以用这个:

# 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

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

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

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

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

不管怎样,这就是 PowerShell:

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

-- A

下面是我如何按照相反的时间顺序列出符合模式(TAG _ PREFIX *)的注释标记。

#!/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

对于大量标记来说效率很高,而且格式灵活:

{ 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/tags添加到 f-e-r 以限制它。

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

我相信这个选项是最近才加入的——当初提出这个问题的时候,以上的答案显然是不可用的。由于这个帖子仍然是谷歌上的第一个热门问题,我想我会把它放在任何人谁滚动到底部寻找一个答案,涉及较少的键入比接受的答案(为我自己的参考,当我忘记这个答案再次下周)。

所有的回答只有列表标签,但如果你想他们在时间顺序,你需要添加 --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

窗口特定的答案为任何人寻找。

(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