如何在Git当前分支中获取最新标签名称?


462

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

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

输出:

a
b
c

我是否应该编写脚本来获取每个标签的日期时间并进行比较?


1
最新创建的标签或按提交日期排序的最新标签?您接受的答案将显示最新创建的标签。如果有人决定更改existig标签,这可能是个问题...
Paebbels

Answers:


412

您可以看一下git describe,它的功能与您的要求接近。


194
带有--abbrev=0它应该返回最近的带注释的标签
JakubNarębski09年

13
返回当前分支
brittohalloran 2011年

42
要获得最新的注释标记它的目标只是当前提交当前分支,使用git describe --exact-match --abbrev=0
Naftuli Kay 2012年

5
这个答案,加上评论,没有为我提供正确的标签。@kilianic提供了正确的解决方案。
赫尔曼·拉德克三世

19
git describe --tags并在github发布页面中比较com的最后一个标记
Adriano Resende

627

要获取最新标签:

git describe --tags

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

git describe --abbrev=0

2
是的,正如手册页所述git describe--abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
Giorgos Kylafas 2012年

22
或者只是git describe --tags
james_womack

5
如果您有两个标记指向同一提交,则此答案(可能还有其他答案)会遇到麻烦。除非标签是带注释的标签,否则我认为git无法区分两者中的哪个是较早创建的。
Paul Lynch

10
这应该是公认的答案。感谢您提交。
crmpicco

6
如果您想直接签出最新标签:git checkout $(git describe --abbrev=0 --tags)
JohnRDOrazio

320

将在所有分支中输出最新标记的提交的标记

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

8
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))@ william-pursell
kilianc

20
这是最好的答案。实际上,它会跨所有分支获取标签,而不仅仅是当前分支,就像当前的“正确”答案一样。
brittohalloran 2011年

61
除了问题专门要求当前分支。
michaeltwofish 2012年

3
@michaeltwofish,当时我还不知道,后来我弄清楚了,并据此更正了我的答案。对于那个很抱歉。
kilianc 2012年

3
注意:即使此标记在另一个分支上,此命令也会返回“最新”标记。
艾伦·志良

47

要获取最新标签,您可以执行以下操作:

$ git for-each-ref refs / tags --sort = -taggerdate --format ='%(refname)'--count = 1

当然,您可以根据需要更改count参数或sort字段。看来您可能想问一个稍微不同的问题,但这在我解释时确实回答了这个问题。


2
这几乎正是我一直在寻找(跨所有分支机构最近的标签),但至少我的版本的Git(1.7.7.6)的标记以相同的顺序两个生产--sort=-authordate--sort=authordate
larsk's

3
啊哈,因为您真正想要的是--sort=-taggerdate。对于标签,authordate并且committerdate为空(因此无用作为排序键)。
larsk's

8
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1甚至更好:)
ChristopheEblé2015年

5
真的,对几乎5年之久的完全正确答案不加评论了吗?没礼貌
威廉·珀塞尔

1
而且--points-at=$SHA会给你标签的提交哈希值。
瑞安

34

这个怎么样?

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

从技术上讲,不一定会为您提供最新的标签,但是可以为您标记的最新提交,这可能是您想要的东西,也可能不是。


该分支不会在当前分支中获取最新标签,而是为任何分支获取最新标签。很棒,因为这正是我所需要的。谢谢Wincent。
jasongregori 2014年

2
如果您需要获取标签匹配模式,可以--tags=<pattern>在中使用rev-list。例如,获取最新版本标签git describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
Wirone

1
$(git describe --contains $(git rev-parse HEAD))
Vaidas Zilionis

谢谢,它起作用了,但是,我不得不添加--tagsgit describe --tags $(git rev-list --tags --max-count=1)
Gianluca Casati

25

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


我从最上面/可接受的答案开始,然后一直往下走。这是实际上为我提供最新标签的第一个答案(不知道为什么,但是普通的旧git describe ...标签会返回一个较早的标签?!)
Jeremy Davis

这是唯一对我有用的。尝试了一些--abbrev=0答案,他们切断了我想要的部分标签。
卢克·戴维斯

22

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

您可能的意思是“哪个标签的创建日期是最新时间”,并且这里的大多数答案都针对该问题。就您的问题而言,您想返回tag c

或者您可能的意思是“哪个标签在开发历史上最接近某个命名分支”,通常是您所在的分支HEAD。在您的问题中,这将返回tag a

当然,这些可能有所不同:

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

想象一下,开发人员将标签标记Zv0.2星期一,然后将标签标记Qv0.1星期二。 在某种程度上,它是v0.1最近的,但是v0.2在发展历史上更接近于HEAD,从某种意义上说,它所走的路径始于更接近HEAD的点。

我认为您通常想要第二个答案,就更接近开发历史了。您可以通过git log v0.2..HEAD对每个标签使用etc 来找出答案。自从以HEAD结尾的路径结束的路径结束以来,这为您提供了HEAD上的提交次数v0.2

这是一个Python脚本,它通过遍历运行此检查的所有标签,然后打印出带有自标签路径偏离以来在HEAD上提交次数最少的标签来执行此操作:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag

git describe所做的事情略有不同,因为它从(例如)HEAD追溯,以查找从HEAD返回历史记录的路径上的第一个标签。用git术语,git describe查找HEAD中“可达”的标签。因此,它将找不到v0.2不在从HEAD返回的路径上的标签,而是从那里发散的路径上的标签。



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

如果您需要多个标签

(git describe --tags有时会给出错误的哈希值,我不知道为什么,但是对我来说--max-count 2不起作用)

这是您如何以相反的时间顺序获取具有最新2个标签名称的列表的方法,在git 1.8.4上可以完美地工作。对于早期版本的git(如1.7。*),输出中没有“ tag:”字符串-只需删除上一个sed调用

如果您需要两个以上的最新标签-将此“ sed 2q”更改为“ sed 5q”或您需要的任何内容

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


这确实很有帮助,如果部署中断,许多开发人员将尝试通过回滚到以前的标记来自动化发布过程。很棒的东西!!!
AkD 2014年

1
进一步说明: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' 其中in %D排除周围的()字符,并且seds开头5q在5之前保留4行,然后打印出'tag:'和第一个','之间的所有字符。因此...假设标签内未使用逗号,则效果很好。
Cometsong

14

所有建议有什么问题马修·布雷特除外)解释,截至本答复的最新信息)?

当您在历史记录的不同点上时,只需在jQuery Git历史记录上运行其他人提供的任何命令然后使用可视标记历史记录表示法检查结果即可(我这样做是为什么您看到此文章):

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

如今,许多项目在与mainline分开的分支中执行发布(以及标记)。

这有很强的理由。只需查看任何完善的JS / CSS项目即可。对于用户约定,它们在DVCS中携带二进制/最小化的发行文件。当然,作为项目维护者,您不想用无用的二进制Blob浪费您的主线差异历史记录,并且不在主线之外执行构建工件的提交

由于Git使用DAG而非线性历史记录- 很难定义距离度量, 所以我们可以说-哦,转速最接近我的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为所需的配方即可!


12

git describe --abbrev=0 --tags

如果看不到最新标记,请在运行该标记之前确保获取原始标记:

git remote update


12
git tag -l ac* | tail -n1

获取带有前缀“ ac”的最后一个标签。例如,以ac1.0.0或命名的标签ac1.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”也会列出所有标签。该模式是外壳通配符(即,使用fnmatch(3)进行匹配)。可以给出多种模式;如果它们中的任何一个匹配,则显示标签。


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

更新资料

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

排序顺序默认为为tag.sort变量配置的值(如果存在),否则为字典顺序。参见git-config(1)。

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

git tag --sort=committerdate

它对我来说不算醒,最后一个标签是2.11.174,但是此打印为2.11.99,因为排序不是按版本进行的
Ali.MD 2013年


5

如果您需要最后两个标签(例如,为了在当前标签和上一个标签之间生成更改日志),以下内容对我有用。我仅在最新标签为的情况下进行了测试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向导,因此我相信它可以得到进一步的改进。我还怀疑,如果提交历史向前发展,它将破坏。我只是分享,以防它对某人有所帮助。


4

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


4

如果要查找在特定分支上应用的最后一个标签,可以尝试以下操作:

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

3

如果您需要一个衬纸,以在当前分支上获得最新的标签名称(按标签日期):

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

我们用它来设置版本号。

输出示例:

v1.0.0

在Windows上也可以使用。


1
在Linux(Debian Stretch)上,我得到-bash: syntax error near unexpected token '('
Jeremy Davis,

1
如果我将该部分用引号引起来(即--format="%(refname:short)"),则跳过该部分--points-at=HEAD。最后一个开关什么都不返回,我猜是因为我HEAD没有被标记?
杰里米·戴维斯

@JeremyDavis,是的,我认为这是因为您HEAD没有被标记。
Markus

2

这是一个旧线程,但是似乎很多人都缺少OP问题的最简单,最简单和最正确的答案:要获取当前分支的最新标签,请使用git describe HEAD。做完了

编辑:您还可以提供任何有效的refname,甚至是remote;即,git describe origin/master将告诉您可以从来源/主站访问的最新标签。


没有任何东西可以保证任何分支都可以处理“最新标签”。两个工作解决方案是for-each-ref命令(stackoverflow.com/a/5261470/515973)和的组合rev-listdescribestackoverflow.com/a/7979255/515973
于连Carsique

1
这没有给我最新的标签。
莫里森

git describe branchname --tags确实为我工作以获取分支上的最新标签(git版本2.12.2)
Rob_M

0

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

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

分支主管:

git checkout master

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

master-1448

分公司风俗:

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}'

0

对于所问的问题,

如何在当前分支中获取最新的标签名称

你要

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

--first-parent告诉git log不要详细说明任何合并的历史,--pretty=%d说仅显示修饰,即任何提交的本地名称。grep -m1说“只匹配一个”,这样您就可以获得最新标签。


0

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

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

0

这里没有多提及未注释的标签与注释的标签。'describe'对带注释的标签起作用,并忽略未注释的标签。

这很丑陋,但是可以完成所请求的工作,并且它不会在其他分支上找到任何标记(并且在以下示例中未在命令中指定的标记上找到:master)

应当对过滤进行优化(合并),但这似乎是可行的。

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

批评表示欢迎,因为我现在要使用它:)


-2

获取最新标签名称的另一种简单方法是

git tag | tail -1

要么

TAG=$(git tag | tail -1)

将其存储在变量中。

git tag列出所有可用的标签,如果结果返回最后一行。tail-1


4
如果不进行排序,这是一个不好的举动。
mjd2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.