在 Git 中获取最新标签的最简单方法是什么?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
输出:
a
b
c
我应该编写一个脚本来获取每个标签的日期时间并进行比较吗?
在 Git 中获取最新标签的最简单方法是什么?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
输出:
a
b
c
我应该编写一个脚本来获取每个标签的日期时间并进行比较吗?
要获取最新的标签(之后的示例输出):
git describe --tags --abbrev=0 # 0.1.0-dev
要获取最新的标记,以及标记对象顶部的附加提交数量及更多:
git describe --tags # 0.1.0-dev-93-g1416689
要获取最新的注释标签:
git describe --abbrev=0
您可以看一下git describe
,它的功能与您的要求接近。
将在所有分支中输出最新标记提交的标记
git describe --tags $(git rev-list --tags --max-count=1)
要获取最新的标签,您可以执行以下操作:
$ git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1
当然,您可以根据需要更改计数参数或排序字段。看来您可能打算问一个稍微不同的问题,但这确实回答了我解释的问题。
这个怎么样?
TAG=$(git describe $(git rev-list --tags --max-count=1))
从技术上讲,不一定会给你最新的标签,而是最新的被标记的提交,这可能是也可能不是你正在寻找的东西。
您可以执行:git describe --tags $(git rev-list --tags --max-count=1)
谈到这里:如何获取最新的标签名称?
“最近”在 git 中可能有两种含义。
您可能的意思是“哪个标签的创建日期最晚”,这里的大多数答案都是针对该问题的。就您的问题而言,您需要返回 tag c
。
或者您可能的意思是“哪个标签在开发历史中最接近某个命名分支”,通常是您所在的分支,HEAD
. 在您的问题中,这将返回 tag a
。
当然,这些可能会有所不同:
A->B->C->D->E->F (HEAD)
\ \
\ X->Y->Z (v0.2)
P->Q (v0.1)
想象一下开发人员标记Z
为v0.2
星期一,然后标记Q
为v0.1
星期二。 v0.1
是最近的,但v0.2
在开发历史上更接近 HEAD,因为它所走的路径始于更接近 HEAD 的点。
我想你通常想要第二个答案,更接近发展历史。您可以通过git log v0.2..HEAD
对每个标签使用 etc 来找到它。这为您提供了 HEAD 上的提交次数,因为以结尾v0.2
的路径与 HEAD 所遵循的路径不同。
这是一个 Python 脚本,它通过遍历所有运行此检查的标签,然后打印出 HEAD 上提交次数最少的标签,因为标签路径不同:
https://github.com/MacPython/terryfy/blob/master/git-closest-tag
git describe
做了一些稍微不同的事情,因为它从(例如)HEAD 回溯以找到从 HEAD 回到历史路径上的第一个标签。在 git 术语中,git describe
查找从 HEAD “可访问”的标签。因此,它不会发现这样v0.2
的标签不在从 HEAD 返回的路径上,而是从那里发散的路径。
git describe --tags
返回当前分支可以看到的最后一个标签
git describe --abbrev=0 --tags
如果您没有看到最新标签,请确保在运行之前获取来源:
git remote update
我不确定为什么对问题的要求没有答案。即所有标签(包括未注释的)并且没有后缀:
git describe --tags --abbrev=0
git tag --sort=committerdate | tail -1
所有建议有什么问题 (除了Matthew Brett的解释,最新的这个答案)?
当您处于不同的历史点时,只需在 jQuery Git 历史上运行其他人提供的任何命令,并使用可视标记历史表示检查结果(我这样做就是您看到这篇文章的原因):
$ git log --graph --all --decorate --oneline --simplify-by-decoration
如今,许多项目在 mainline 的单独分支中执行发布(以及标记)。
这有充分的理由。只要看看任何完善的 JS/CSS 项目。对于用户约定,它们在 DVCS 中携带二进制/缩小版本文件。自然地,作为项目维护者,您不想用无用的二进制 blob 破坏您的 mainline差异历史记录,并在 mainline 之外执行构建工件的提交。
因为 Git 使用 DAG 而不是线性历史 -很难定义距离度量 ,所以我们可以说 - 哦,rev 最接近我的HEAD
!
我开始了自己的旅程(看看里面,我没有将精美的证明图片复制到这篇长篇文章中):
目前,随着有用性的降低,我对标签和修订之间的距离有 4 个合理的定义:
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
如果您的项目历史在提交上有奇怪的日期(因为 rebase 或其他历史重写或某些白痴忘记更换 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
获取带有前缀"ac"的最后一个标签。例如,以ac1.0.0
、 或命名的标记ac1.0.5
。1.0.0
其他名为, 的标签1.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 通配符(即,使用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
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 调用
如果您想要超过 2 个最新标签 - 将此“sed 2q”更改为“sed 5q”或您需要的任何内容
然后您可以轻松地将每个标签名称解析为变量左右。
CI/CD 过程中的问题describe
是您可能会遇到fatal: no tags can describe
错误。
这将发生,因为,每git describe --help
:
该命令查找可从提交中访问的最新标记。
如果您想要 repo 中的最新标签,无论您所在的分支是否可以到达该标签,通常是因为它不是当前分支树的一部分,此命令将为您提供整个 repo 中最近创建的标签:
git tag -l --sort=-creatordate | head -n 1
如果您需要最后两个标签(例如,为了在当前标签和前一个标签之间生成更改日志),以下内容适用于我。我只在最新标签是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 for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD
我们使用它来设置设置中的版本号。
输出示例:
v1.0.0
也适用于 Windows。
我的第一个想法是你可以使用git rev-list HEAD
,它按时间倒序列出所有转速,结合git tag --contains
. 当您找到一个git tag --contains
产生非空列表的 ref 时,您已经找到了最新的标签。
如果要查找应用于特定分支的最后一个标签,可以尝试以下操作:
git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")
这是一个旧线程,但似乎很多人都错过了对 OP 问题的最简单、最简单和最正确的答案:要获取当前分支的最新标签,请使用git describe HEAD
. 完毕。
编辑:您还可以提供任何有效的引用名,甚至是遥控器;即,git describe origin/master
将告诉您可以从 origin/master 访问的最新标签。
git tag --sort=-refname | awk 'match($0, /^[0-9]+\.[0-9]+\.[0-9]+$/)' | head -n 1
这个在所有与语义版本控制匹配的分支中获取最新标签。
要仅在以当前分支为前缀的当前分支/标签名称上获取最新标签,我必须执行以下操作
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}'
对于所问的问题,
如何获取当前分支中最新的标签名称
你要
git log --first-parent --pretty=%d | grep -m1 tag:
--first-parent
告诉git log
不要详细说明任何合并的历史,--pretty=%d
说只显示装饰,即任何提交的本地名称。grep -m1
说“只匹配一个”,所以你只会得到最新的标签。
如果您的标签是可排序的:
git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1
这里没有太多提到未注释的标签和带注释的标签。'describe' 适用于带注释的标签并忽略未注释的标签。
这很丑陋,但可以完成所要求的工作,并且它不会在其他分支上找到任何标签(而不是在命令中指定的标签上:下面示例中的 master )
过滤应该被优化(合并),但同样,这似乎是工作。
git log --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1
欢迎批评,因为我现在要使用它:)