简体   繁体   English

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

[英]How can I get the latest tag name in current branch in Git?

What's the simplest way to get the most recent tag in Git?在 Git 中获取最新标签的最简单方法是什么?

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

output:输出:

a
b
c

Should I write a script to get each tag's datetime and compare them?我应该编写一个脚本来获取每个标签的日期时间并进行比较吗?

To get the most recent tag (example output afterwards):获取最新的标签(之后的示例输出):

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

To get the most recent tag, with the number of additional commits on top of the tagged object & more:要获取最新的标记,以及标记对象之上的附加提交数量等:

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

To get the most recent annotated tag:要获取最新的注释标签:

git describe --abbrev=0

您可以查看git describe ,它的功能与您的要求相近。

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

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

To get the most recent tag, you can do:要获取最新的标签,您可以执行以下操作:

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

Of course, you can change the count argument or the sort field as desired.当然,您可以根据需要更改计数参数或排序字段。 It appears that you may have meant to ask a slightly different question, but this does answer the question as I interpret it.看起来你可能想问一个稍微不同的问题,但这确实回答了我解释的问题。

How about this?这个怎么样?

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

Technically, won't necessarily get you the latest tag, but the latest commit which is tagged, which may or may not be the thing you're looking for.从技术上讲,不一定会为您提供最新的标签,而是带标签的最新提交,这可能是您正在寻找的东西,也可能不是。

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

git describe --tags

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

"Most recent" could have two meanings in terms of git.就 git 而言,“最近”可能有两种含义。

You could mean, "which tag has the creation date latest in time", and most of the answers here are for that question.您可能的意思是“哪个标签的创建日期是最新的”,这里的大部分答案都是针对该问题的。 In terms of your question, you would want to return tag c .就您的问题而言,您希望返回标签c

Or you could mean "which tag is the closest in development history to some named branch", usually the branch you are on, HEAD .或者您可以指“哪个标签在开发历史上最接近某个命名分支”,通常是您所在的分支HEAD In your question, this would return tag a .在您的问题中,这将返回 tag a

These might be different of course:这些当然可能不同:

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

Imagine the developer tag'ed Z as v0.2 on Monday, and then tag'ed Q as v0.1 on Tuesday.想象一下,开发人员在星期一将Z标记为v0.2 ,然后在星期二将Q v0.1v0.1 v0.1 is the more recent, but v0.2 is closer in development history to HEAD, in the sense that the path it is on starts at a point closer to HEAD. v0.1是最近的,但v0.2在开发历史上更接近 HEAD,因为它所走的路径始于更接近 HEAD 的点。

I think you usually want this second answer, closer in development history.我想你通常想要第二个答案,在发展历史上更接近。 You can find that out by using git log v0.2..HEAD etc for each tag.您可以通过对每个标签使用git log v0.2..HEAD等来发现这一点。 This gives you the number of commits on HEAD since the path ending at v0.2 diverged from the path followed by HEAD.这为您提供了 HEAD 上的提交次数,因为以v0.2结尾的路径与后跟 HEAD 的路径不同。

Here's a Python script that does that by iterating through all the tags running this check, and then printing out the tag with fewest commits on HEAD since the tag path diverged:这是一个 Python 脚本,它通过遍历运行此检查的所有标签来执行此操作,然后打印出由于标签路径不同而在 HEAD 上提交次数最少的标签:

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

git describe does something slightly different, in that it tracks back from (eg) HEAD to find the first tag that is on a path back in the history from HEAD. git describe做了一些稍微不同的事情,因为它从(例如)HEAD 回溯以找到从 HEAD 返回的历史路径上的第一个标签。 In git terms, git describe looks for tags that are "reachable" from HEAD.在 git 术语中, git describe查找可从 HEAD “访问”的标签。 It will therefore not find tags like v0.2 that are not on the path back from HEAD, but a path that diverged from there.因此,它不会找到像v0.2这样不在 HEAD 返回路径上的标签,而是从那里发散的路径。

I'm not sure why there are no answers to what the question is asking for.我不知道为什么这个问题没有答案。 ie All tags (non-annotated included) and without the suffix:即所有标签(包括非注释)并且没有后缀:

git describe --tags --abbrev=0
git describe --abbrev=0 --tags

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

git remote update

What is wrong with all suggestions (except Matthew Brett explanation, up to date of this answer post)?所有建议都有什么问题(除了Matthew Brett 的解释,这个回答帖子的最新版本)?

Just run any command supplied by other on jQuery Git history when you at different point of history and check result with visual tagging history representation (I did that is why you see this post):当您处于不同的历史记录点时,只需在 jQuery Git 历史记录上运行其他人提供的任何命令并使用可视化标记历史记录表示检查结果(我这样做就是您看到这篇文章的原因):

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

Todays many project perform releases (and so tagging) in separate branch from mainline .今天,许多项目在与 mainline 不同的分支中执行发布(以及标记)。

There are strong reason for this.这是有充分理由的。 Just look to any well established JS/CSS projects.只需查看任何完善的 JS/CSS 项目即可。 For user conventions they carry binary/minified release files in DVCS.对于用户约定,他们在 DVCS 中携带二进制/缩小的发布文件。 Naturally as project maintainer you don't want to garbage your mainline diff history with useless binary blobs and perform commit of build artifacts out of mainline .当然作为项目的维护者,你不想垃圾无用的二进制块的主线差异的历史和执行构建工件犯了主线

Because Git uses DAG and not linear history - it is hard to define distance metric so we can say - oh that rev is most nearest to my HEAD !因为 Git 使用 DAG 而不是线性历史 -很难定义距离度量,所以我们可以说 - 哦,rev 最接近我的HEAD

I start my own journey in (look inside, I didn't copy fancy proof images to this long post):我开始了我自己的旅程(看看里面,我没有将花哨的证明图片复制到这篇长篇文章中):

What is nearest tag in the past with respect to branching in Git? 关于 Git 中的分支,过去最近的标签是什么?

Currently I have 4 reasonable definition of distance between tag and revision with decreasing of usefulness:目前我有 4 个合理的标签和修订之间的距离定义,随着实用性的降低:

  • length of shortest path from HEAD to merge base with tagHEAD合并 base和 tag的最短路径长度
  • date of merge base between HEAD and tag HEAD和标签之间的合并基准日期
  • number of revs that reachable from HEAD but not reachable from tag可从 HEAD 访问但无法从标签访问的转数
  • date of tag regardless merge base不考虑合并基础的标签日期

I don't know how to calculate length of shortest path .我不知道如何计算最短路径的长度

Script that sort tags according to date of merge base between HEAD and tag:根据HEAD和标签之间合并基础的日期对标签进行排序的脚本:

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

It usable on most of projects.它可用于大多数项目。

Script that sort tags according to number of revs that reachable from HEAD but not reachable from tag:根据从 HEAD 可到达但从标签不可到达的转数对标签进行排序的脚本:

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

If your project history have strange dates on commits (because of rebases or another history rewriting or some moron forget to replace BIOS battery or other magics that you do on history) use above script.如果你的项目历史在提交时有奇怪的日期(因为 rebase 或其他历史重写,或者一些白痴忘记更换 BIOS 电池或其他你在历史上做的魔法)使用上面的脚本。

For last option ( date of tag regardless merge base ) to get list of tags sorted by date use:对于最后一个选项(标签,无论合并基础日期)获得的按日期排序使用标签列表:

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

To get known current revision date use:要获得已知的当前修订日期,请使用:

$ git log --max-count=1

Note that git describe --tags have usage on its own cases but not for finding human expected nearest tag in project history .请注意, git describe --tags在它自己的情况下有使用,但不能用于在项目历史中查找人类预期的最近标签

NOTE You can use above recipes on any revision, just replace HEAD with what you want!注意您可以在任何版本中使用上述配方,只需将HEAD替换为您想要的!

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

IF YOU NEED MORE THAN ONE LAST TAG如果您需要不止一个标签

(git describe --tags sometimes gives wrong hashes, i dont know why, but for me --max-count 2 doesnt work) (git describe --tags 有时会给出错误的哈希值,我不知道为什么,但对我来说 --max-count 2 不起作用)

this is how you can get list with latest 2 tag names in reverse chronological order, works perfectly on git 1.8.4.这是您如何按时间倒序获取最新 2 个标签名称的列表,在 git 1.8.4 上完美运行。 For earlier versions of git(like 1.7.*), there is no "tag: " string in output - just delete last sed call对于早期版本的 git(如 1.7.*),输出中没有“tag:”字符串 - 只需删除最后一个 sed 调用

If you want more than 2 latest tags - change this "sed 2q" to "sed 5q" or whatever you need如果您需要 2 个以上的最新标签 - 将此“sed 2q”更改为“sed 5q”或您需要的任何标签

Then you can easily parse every tag name to variable or so.然后您可以轻松地将每个标签名称解析为变量左右。

git tag -l ac* | tail -n1

Get the last tag with prefix "ac" .获取带有前缀"ac"的最后一个标签。 For example, tag named with ac1.0.0 , or ac1.0.5 .例如,以ac1.0.0ac1.0.5命名的标签。 Other tags named 1.0.0 , 1.1.0 will be ignored.其他名为1.0.01.1.0标签将被忽略。

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

Get the last tag, whose first char is 0-9 .获取最后一个标签,其第一个字符是0-9 So, those tags with first char az will be ignored.因此,那些带有第一个字符az标签将被忽略。

More info更多信息

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

git tag -l <pattern>

List tags with names that match the given pattern (or all if no pattern is given).列出名称与给定模式匹配的标签(如果没有给出模式,则列出所有标签)。 Running "git tag" without arguments also lists all tags.不带参数运行“git tag”也会列出所有标签。 The pattern is a shell wildcard (ie, matched using fnmatch(3)).该模式是一个 shell 通配符(即,使用 fnmatch(3) 进行匹配)。 Multiple patterns may be given;可以给出多个模式; if any of them matches, the tag is shown.如果其中任何一个匹配,则显示标签。


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

Update更新

With git tag --help , about the sort argument.使用git tag --help ,关于sort参数。 It will use lexicorgraphic order by default, if tag.sort property doesn't exist.如果tag.sort属性不存在, tag.sort默认使用lexicorgraphic order

Sort order defaults to the value configured for the tag.sort variable if it exists, or lexicographic order otherwise.如果存在,排序顺序默认为为 tag.sort 变量配置的值,否则为字典顺序。 See git-config(1).参见 git-config(1)。

After google, someone said git 2.8.0 support following syntax.在google之后,有人说git 2.8.0支持以下语法。

git tag --sort=committerdate

The following works for me in case you need last two tags (for example, in order to generate change log between current tag and the previous tag).如果您需要最后两个标签(例如,为了在当前标签和前一个标签之间生成更改日志),以下内容对我有用。 I've tested it only in situation where the latest tag was the HEAD .我仅在最新标签是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_"`

It suits my needs, but as I'm no git wizard, I'm sure it could be further improved.它适合我的需求,但由于我不是 git 向导,我相信它可以进一步改进。 I also suspect it will break in case the commit history moves forward.我还怀疑它会在提交历史向前移动的情况下中断。 I'm just sharing in case it helps someone.我只是分享以防它对某人有帮助。

My first thought is you could use git rev-list HEAD , which lists all the revs in reverse chronological order, in combination with git tag --contains .我的第一个想法是你可以使用git rev-list HEAD ,它以相反的时间顺序列出所有的转速,结合git tag --contains When you find a ref where git tag --contains produces a nonempty list, you have found the most recent tag(s).当您找到git tag --contains生成非空列表的引用时,您就找到了最新的标签。

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

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

If you need a one liner which gets the latest tag name (by tag date) on the current branch :如果您需要一个在当前分支上获取最新标签名称(按标签日期)的班轮:

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

We use this to set the version number in the setup.我们使用它来设置设置中的版本号。

Output example:输出示例:

v1.0.0

Works on Windows, too.也适用于 Windows。

This is an old thread, but it seems a lot of people are missing the simplest, easiest, and most correct answer to OP's question: to get the latest tag for the current branch , you use git describe HEAD .这是一个旧线程,但似乎很多人都错过了 OP 问题的最简单、最简单和最正确的答案:要获取当前分支的最新标签,您可以使用git describe HEAD Done.完毕。

Edit: you can also supply any valid refname, even remotes;编辑:您还可以提供任何有效的引用名称,甚至是遥控器; ie, git describe origin/master will tell you the latest tag that can be reached from origin/master.即, git describe origin/master会告诉你可以从 origin/master 到达的最新标签。

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

这个获取所有分支中与语义版本控制相匹配的最新标签。

To get the latest tag only on the current branch/tag name that prefixes with current branch, I had to execute the following要仅在以当前分支为前缀的当前分支/标记名称上获取最新标记,我必须执行以下操作

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

Branch master:分店主:

git checkout master

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

master-1448

Branch custom:分行习俗:

git checkout 9.4

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

9.4-6

And my final need to increment and get the tag +1 for next tagging.我最后需要增加并获取标记 +1 以进行下一次标记。

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

For the question as asked,对于所问的问题,

How to get the latest tag name in the current branch如何获取当前分支中最新的标签名

you want你要

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

--first-parent tells git log not to detail any merged histories, --pretty=%d says to show only the decorations ie local names for any commits. --first-parent告诉git log不要详细说明任何合并的历史记录,-- --pretty=%d表示只显示装饰,即任何提交的本地名称。 grep -m1 says "match just one", so you get just the most-recent tag. grep -m1说“只匹配一个”,所以你只得到最近的标签。

如果您的标签可排序:

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

Not much mention of unannotated tags vs annotated ones here.这里没有太多提及未注释的标签与带注释的标签。 'describe' works on annotated tags and ignores unannotated ones. 'describe' 适用于带注释的标签并忽略未注释的标签。

This is ugly but does the job requested and it will not find any tags on other branches (and not on the one specified in the command: master in the example below)这是丑陋的,但完成了请求的工作,它不会在其他分支上找到任何标签(而不是在命令中指定的那个:master 在下面的示例中)

The filtering should prob be optimized (consolidated), but again, this seems to the the job.过滤应该被优化(合并),但同样,这似乎是工作。

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

Critiques welcome as I am going now to put this to use :)欢迎批评,因为我现在要使用它:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM