如何列出特定git分支中的所有标签 [英] How to list all tags within a certain git branch

查看:132
本文介绍了如何列出特定git分支中的所有标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在git回购中有几个分支。我想知道是否有一个命令列出了某个分支中的所有标签,而不是整个回购中的所有标签。



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

图1中,所有标签都有它们的哈希列表(标记的两个标签具有相同的哈希/提交)

图2,你可以看到我在一个名为b的分支上
图片3,我查询了哪个分支包含两个标签的散列(都有相同的散列),并且表示他们在分支b(我目前使用的分支)上



图4描述了分支标签,它只给了我一个标签



图片5还描述了应该指向的哈希标签用两个标签标记的提交,它只会再次显示一个标签

解决方案

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

  git for-each-ref refs / tags | grep HASH 

或者如果你在Windows上并且不使用Cygwin或类似的话:

  git for-each-ref refs / tags |找到HASH

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

  git for -each-ref refs / tags | grep HASH | sed -rs /.* refs\ / tags\ /(.*)/ \ 1 /

关于最初的问题:

这遍历所有分支中的所有标签,询问git哪些分支包含每个标签和基于提供的分支名称的过滤器 - 但要注意,它是超级缓慢

  git for-each-ref refs / tags  - 格式%(refname)|同时阅读x 

如果git branch --contains $ x | grep -q^ [*] master $
then echo $ x
fi
done

以下取自其他答案很多更快:

  git log  - 简化装饰 - 装饰--pretty = onelinemaster| fgrep'标签:'

...但是如果多个标签指向相同的提交,它会产生:

 (HEAD,tag:Test-Tag1,tag:Test-Tag2,Test-Tag3,fork / devel,devel) 
(tag:Another-Tag)
(tag:And-Another)

(三个标签 Test-Tag * 指向相同的提交)



我写了一个Python脚本,只有名称,每行一个(仅在Windows上测试过):

 从子进程导入os 
导入调用

print( - * 80)

dirpath = rD:\Projekte\arangodb#<<把你的回购根路径放在这里!

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

#可能直接从标准输入读取somewhow而不是写入文件...
#在本地主分支中写入提交到文件
os.chdir(dirpath)
os.system(git rev-list refs / heads / master>+ commitspath)

tags = {}
用于os.listdir(tagdir)中的标记文件:
打开(os.path.join(tagdir,tagfile),r)作为文件:
tags [file.read()。strip()] = tagfile

tags_set = set(标签)

提交= {}
以打开(commitspath,r)作为文件:
用于文件中的行:
提交[行。 strip()] = 1
os.remove(commitspath)

commits_set = set(提交)

为排序提交(commits_set.intersection(tags_set), key = lambda x:tags [x]):
print(tags [commit])

结果:

  Test-Tag1 
Test-Tag2
Test-Tag3
另一个标记
另一个

提交散列可以随意打印标签,只需将最后一行修改为 print(commit,tags [commit])。脚本似乎表现得非常好!



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

  git tag --list --branch master 


I have a couple of branches in my git repo. I would like to know if there is a command that lists all the tags within a certain branch not all the tags in the whole repo.

I tried git tag --contains. but it didn't work as expected.

Image 1, there's a list of all the tags with their hashes (the marked two tags have the same hash/commit) Image 2, as you can see I'm on a branch called "b" Image 3, I queried which branch contains the hash of both tags (both have same hash) and it said they are on branch "b" (the one I'm currently on)

Image 4, describing the branch tags, It only gave me ONE tag

Image 5, also describing the tags of the hash that is supposed to point to the commit that is tagged with both tags, it only shows ONE tag again

解决方案

To print all tags, that point to a certain commit, you can do:

git for-each-ref refs/tags | grep HASH

Or if you are on Windows and don't use Cygwin or similar:

git for-each-ref refs/tags | find "HASH"

If you want the tag name only, you can't use Git's --format , because we need it for grep'ing. Thus we need to strip the stuff we aren't interested in away in the final step (Linux/Cygwin):

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

Regarding the initial question:

This iterates over all tags in all branches, asks git which branches contain each tag and filters based on the supplied branch name - but be warned, it's super slow:

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

The following taken from another answer is much faster:

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

... but if multiple tags point to the same commit, it will produce:

 (HEAD, tag: Test-Tag1, tag: Test-Tag2, Test-Tag3, fork/devel, devel)
 (tag: Another-Tag)
 (tag: And-Another)

(three tags Test-Tag* pointing to the same commit)

I wrote a Python script that outputs tag names only, one per line (tested on Windows only):

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

Result:

Test-Tag1
Test-Tag2
Test-Tag3
Another-Tag
And-Another

The commit hash could optionally be printed too for every tag, simply modify the last line to print(commit, tags[commit]). The script seems to perform very well by the way!

Ideally, git would support something like the following command to avoid all these workarounds:

git tag --list --branch master

这篇关于如何列出特定git分支中的所有标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆