如何在Git的当前分支中获得最新的标记名称?

在Git中获取最新标签的最简单方法是什么?

git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag

输出:

a
b
c

我应该写一个脚本来获得每个标记的日期时间并比较它们吗?

399986 次浏览

您可以看一下git describe,它的功能与您所要求的类似。

我的第一个想法是你可以使用git rev-list HEAD,它以倒序顺序列出所有转速,与git tag --contains相结合。当您找到一个引用,其中git tag --contains产生一个非空列表时,您已经找到了最新的标记。

这个怎么样?

# EYZ0

从技术上讲,不一定会得到最新的标签,但会得到标记的最新提交,这可能是你要找的东西,也可能不是。

要获得最新的标签,你可以这样做:

$ git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1
当然,您可以根据需要更改count参数或排序字段。似乎 你可能想问一个稍微不同的问题,但这确实回答了我的理解。

要获得最新的标签(后面的示例输出):

git describe --tags --abbrev=0   # 0.1.0-dev

要获得最近的标记,在标记对象&更多:

git describe --tags              # 0.1.0-dev-93-g1416689

要获得最新的带注释的标签:

git describe --abbrev=0

将输出的标签的最新标签提交跨所有分支

git describe --tags $(git rev-list --tags --max-count=1)

# EYZ0

返回当前分支能看到的最后一个标记

如果您需要最后两个标记(例如,为了生成当前标记和前一个标记之间的更改日志),下面的工作对我来说是有效的。我只在最新标签为HEAD的情况下测试过它。

PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`


GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`

它适合我的需求,但因为我不是git巫师,我相信它可以进一步改进。我还怀疑如果提交历史向前移动,它会中断。我只是想说点有用的。

git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed  's ......  '

如果你还需要更多的标签

(git描述-标签有时会给出错误的哈希值,我不知道为什么,但对我来说-max-count 2不工作)

这是如何以倒序顺序获得最新2个标签名称的列表,在git 1.8.4上完美工作。 对于早期版本的git(如1.7.*),输出中没有“tag:”字符串——只是删除最后一次sed调用

如果你想要两个以上的最新标签-将这个“sed 2q”改为“sed 5q”或任何你需要的

然后,您可以轻松地将每个标记名称解析为变量。

就git而言,“最近的”可能有两种含义。

您的意思可能是“哪个标签的创建日期最近”,这里的大多数答案都是关于这个问题的。对于您的问题,您可能希望返回标签c

或者您可以表示“哪个标记在开发历史中最接近某个已命名的分支”,通常是您所在的分支,HEAD。在您的问题中,这将返回标签a

当然,这些可能是不同的:

A->B->C->D->E->F (HEAD)
\     \
\     X->Y->Z (v0.2)
P->Q (v0.1)

想象一下,开发人员在周一将Z标记为v0.2,然后在周二将Q标记为v0.1v0.1是最近的,但v0.2在开发历史上更接近HEAD,从某种意义上说,它所处的路径开始于更接近HEAD的点。

我认为你通常想要第二个答案,更接近开发历史。您可以通过为每个标记使用git log v0.2..HEAD等来找到它。这为您提供了HEAD上的提交数量,因为结束于v0.2的路径与HEAD后面的路径不同。

下面是一个Python脚本,它通过遍历所有运行该检查的标记来实现这一点,然后打印出在HEAD上提交最少的标记,因为标记路径发散了:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag < a href = " https://github.com/MacPython/terryfy/blob/master/git-closest-tag " > < / >

git describe做了一些稍微不同的事情,因为它从(例如)HEAD跟踪,以找到从HEAD返回的历史路径上的第一个标记。在git术语中,git describe查找从HEAD“可到达”的标记。因此,它不会找到像v0.2这样不在从HEAD返回的路径上的标记,而是从那里偏离的路径。

git describe --abbrev=0 --tags

如果你没有看到latest标签,请确保在运行之前获取origin:

git remote update

什么是错误的和所有的建议(除了马修·布雷特的解释,到目前为止的这篇回答帖子)?

当你在不同的历史时期和检查结果视觉标记历史表示(我是做了,这就是为什么你看到这篇文章)时,运行其他在jQuery Git历史上提供的任何命令:

$ git log --graph --all --decorate --oneline --simplify-by-decoration

今天,许多项目执行发布(因此标记)分支与主线分开

这里有强大的原因。看看那些已经建立好的JS/CSS项目就知道了。出于用户约定,它们在DVCS中携带二进制/最小化的发布文件。当然,作为项目维护者,你不希望用无用的二进制blobs来破坏主线diff历史,并执行构建工件脱离主线的提交。

因为Git使用DAG而不是线性历史,它是很难定义距离度量,所以我们可以说,哦,rev最接近我的HEAD!

我开始了我自己的旅程(看看里面,我没有复制花哨的证明图片到这篇长文章中):

关于Git中的分支,过去最近的标签是什么?< / >

目前我对标签与修订之间的距离有4个合理的定义,但有用性在降低:

  • 最短路径长度HEAD合并基础带标签
  • HEAD和标签之间的合并基础日期
  • 转数,从HEAD可达,但不能从标签
  • 标签的日期不管合并基础

我不知道如何计算最短路径长度

根据合并基础日期HEAD和标签之间排序的脚本:

$ git tag \
| while read t; do \
b=`git merge-base HEAD $t`; \
echo `git log -n 1 $b --format=%ai` $t; \
done | sort

它适用于大多数项目。

脚本,根据转数标签排序,可从HEAD,但不能从标签:

$ git tag \
| while read t; do echo `git rev-list --count $t..HEAD` $t; done \
| sort -n

如果你的项目历史在提交时有奇怪的日期(因为重基或另一个历史重写或一些白痴忘记更换BIOS电池或其他你对历史所做的魔法),请使用上面的脚本。

对于最后一个选项(标签的日期,不管合并基础),以获得按日期排序的标签列表:

$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r

要获得当前的修订日期,请使用:

$ git log --max-count=1

注意,git describe --tags在它自己的情况下使用,但不是用于查找人类期望在项目历史中最接近的标签

你可以在任何修订中使用上述食谱,只需将HEAD替换为你想要的!

git tag -l ac* | tail -n1

获取带有“交流”前缀的最后一个标记。例如,以ac1.0.0ac1.0.5命名的标记。其他名为1.0.01.1.0的标签将被忽略。

git tag -l [0-9].* | tail -n1

获取最后一个标记,其第一个字符是0-9。因此,首字符为a-z的标签将被忽略。

更多信息

git tag --help # Help for `git tag`

git tag -l <pattern>

列出名称与给定模式匹配的标签(如果不匹配则全部匹配) 给出了模式)。运行不带参数的“git tag”也会列出列表 所有的标记。模式是一个shell通配符(即匹配使用 :(3))。可以给出多个模式;如果有的话


tail -n <number> # display the last part of a file
tail -n1 # Display the last item

更新

对于git tag --help,关于sort参数。如果tag.sort属性不存在,它将默认使用lexicorgraphic order

< p >排序顺序 默认为为标记配置的值。对变量进行排序 存在,否则按字典顺序。看到git-config (1) . < / p >

在谷歌之后,有人说 git 2.8.0支持以下语法。

git tag --sort=committerdate

这是一个旧的线程,但似乎很多人都忽略了OP的问题最简单、最简单、最正确的答案:要获得当前分支的最新标记,您使用git describe HEAD。完成了。

编辑:您还可以提供任何有效的refname,甚至远程;例如,git describe origin/master将告诉您从原点/主节点可以到达的最新标记。

为了只获取当前分支/以当前分支为前缀的标记名上的最新标记,我必须执行以下命令

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH

# EYZ0

git checkout master


BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH


master-1448

# EYZ0

git checkout 9.4


BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH


9.4-6

我最后需要做的是增加并获得标签+1用于下一个标签。

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags  --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'

对于刚才的问题,

如何获得当前分支中最新的标记名称

你想要的

git log --first-parent --pretty=%d | grep -m1 tag:

--first-parent告诉git log不要详细描述任何合并的历史,--pretty=%d说只显示装饰,即任何提交的本地名称。grep -m1表示“只匹配一个”,所以你只得到最近的标签。

如果你想找到应用在特定分支上的最后一个标签,你可以尝试以下方法:

git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")

如果你的标签是可排序的:

git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1

你可以执行:git describe --tags $(git rev-list --tags --max-count=1)这里说的:如何获取最新标签名称?

如果你需要一个在当前分支上获得最新标签名称(通过标签日期)的一行程序:

git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD

我们使用它来设置设置中的版本号。

输出的例子:

v1.0.0

也适用于Windows。

git tag --sort=committerdate | tail -1

这里没有过多地提到无注释标记和带注释标记。'describe'作用于带注释的标签,而忽略未带注释的标签。

这是丑陋的,但完成了所要求的工作,它将不会在其他分支上找到任何标记(而不是在下面的例子中命令:master中指定的分支上)

过滤应该被优化(巩固),但这似乎是工作。

git log  --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1

欢迎批评,因为我现在要把它用起来:)

我不知道为什么这个问题没有答案。即所有标签(包括无注释的标签),不带后缀:

git describe --tags --abbrev=0
git tag --sort=-refname | awk 'match($0, /^[0-9]+\.[0-9]+\.[0-9]+$/)' | head -n 1

它在所有与语义版本匹配的分支中获取最新的标记。

在CI/CD进程中使用describe的问题是您可能会遇到fatal: no tags can describe错误。

这是因为,根据git describe --help:

该命令查找最新的标记从提交可达

如果你想要repo中最新的标签,不管你所在的分支是否可以到达这个标签,通常是因为它不是当前分支树的一部分,这个命令会给你整个repo中最近创建的标签:

git tag -l --sort=-creatordate | head -n 1