如何列出某个git分支中的所有标记

mkm*_*afa 5 git

我的git仓库中有几个分支.我想知道是否有一个命令列出了某个分支中的所有标记而不是整个仓库中的所有标记.

我试过了 git tag --contains.但它没有按预期工作.

图1,有一个带有散列的所有标签的列表(标记的两个标签具有相同的散列/提交) 在此输入图像描述 图2,你可以看到我在一个名为"b"的分支上 在此输入图像描述 图3,我查询哪个分支包含两个标签的哈希值(两者都有相同的哈希),并且它表示它们位于分支"b"(我当前正在使用的那个)上在此输入图像描述

图4,描述了分支标签,它只给了我一个标签在此输入图像描述

图5,也描述了应该指向用两个标签标记的提交的哈希的标签,它只再次显示一个标签在此输入图像描述

qwe*_*guy 11

使用git tag --sort='creatordate' --merged列出所有标签访问/可到达,从头部,并将它们按时间顺序进行排序.

如果你不想要HEAD,你可以指定一个ref git tag --sort='creatordate' --merged mybranch


CoD*_*anX 7

要打印指向某个提交的所有标记,您可以执行以下操作:

git for-each-ref refs/tags | grep HASH
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用的是Windows并且不使用Cygwin或类似的:

git for-each-ref refs/tags | find "HASH"
Run Code Online (Sandbox Code Playgroud)

如果你只想要标签名称,你不能使用Git --format,因为我们需要它来进行grep'ing.因此,我们需要在最后一步(Linux/Cygwin)中删除我们不感兴趣的东西:

git for-each-ref refs/tags | grep HASH | sed -r "s/.*refs\/tags\/(.*)/\1/"
Run Code Online (Sandbox Code Playgroud)

关于最初的问题:

这会迭代所有分支中的所有标记,询问git哪些分支包含每个标记并根据提供的分支名称进行过滤 - 但要注意,它超级慢:

git for-each-ref refs/tags --format "%(refname)" | while read x
do
    if git branch --contains $x | grep -q "^[ *] master$"
        then echo $x
    fi
done
Run Code Online (Sandbox Code Playgroud)

以下从另一个答案中获得的更快:

git log --simplify-by-decoration --decorate --pretty=oneline "master" | fgrep 'tag: '
Run Code Online (Sandbox Code Playgroud)

...但是如果多个标签指向同一个提交,它将产生:

 (HEAD, tag: Test-Tag1, tag: Test-Tag2, Test-Tag3, fork/devel, devel)
 (tag: Another-Tag)
 (tag: And-Another)
Run Code Online (Sandbox Code Playgroud)

(三个标记Test-Tag*指向同一个提交)

我编写了一个Python脚本,仅输出标记名称,每行一个(仅在Windows上测试):

import os
from subprocess import call

print("-" * 80)

dirpath = r"D:\Projekte\arangodb" # << Put your repo root path here!

tagdir = os.path.join(dirpath, ".git", "refs", "tags")
commitspath = os.path.join(dirpath, "_commit_list.tmp")

# could probably read from stdin directly somewhow instead of writing to file...
# write commits in local master branch to file
os.chdir(dirpath)
os.system("git rev-list refs/heads/master > " + commitspath)

tags = {}
for tagfile in os.listdir(tagdir):
    with open(os.path.join(tagdir, tagfile), "r") as file:
        tags[file.read().strip()] = tagfile

tags_set = set(tags)

commits = {}
with open(commitspath, "r") as file:
    for line in file:
        commits[line.strip()] = 1
os.remove(commitspath)

commits_set = set(commits)

for commit in sorted(commits_set.intersection(tags_set), key=lambda x: tags[x]):
    print(tags[commit])
Run Code Online (Sandbox Code Playgroud)

结果:

Test-Tag1
Test-Tag2
Test-Tag3
Another-Tag
And-Another
Run Code Online (Sandbox Code Playgroud)

也可以选择为每个标签打印提交哈希,只需将最后一行修改为print(commit, tags[commit]).顺便说一句,脚本似乎表现得非常好!

理想情况下,git会支持类似下面的命令来避免所有这些变通方法:

git tag --list --branch master
Run Code Online (Sandbox Code Playgroud)

  • 我正在研究'git tag --merged',这将是最简单的方法:) (3认同)
  • 你去https://github.com/KarthikNayak/git/commits/exp,我建议你跳过前几个提交.我同意Jeff的说法,这个名字来自branch.c中的选项,虽然你的约束是我们想要的分支,检查标签,选项可以扩展为任何refs,所以合并的方式也有意义 (2认同)