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

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

输出:

a
b
c

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


当前回答

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

git describe --tags --abbrev=0

其他回答

所有的建议都有什么问题(除了Matthew Brett的解释,到目前为止)?

当你在不同的历史点时,只需运行其他jQuery Git历史上提供的任何命令,并使用可视化标签历史表示检查结果(我这样做就是为什么你看到这篇文章):

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

今天,许多项目在独立于主线的分支中执行发布(以及标记)。

这是有充分理由的。看看那些已经建立好的JS/CSS项目就知道了。出于用户约定,它们在DVCS中携带二进制/最小化的发布文件。当然,作为项目维护者,你不希望用无用的二进制blob来垃圾你的主线差异历史,并在主线之外执行构建工件的提交。

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

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

关于Git中的分支,过去最近的标记是什么?

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

从HEAD到合并base与tag的最短路径长度 HEAD和标签之间合并基础的日期 从HEAD可达但从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

它适用于大多数项目。

根据可从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而言,“最近的”可能有两种含义。

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

或者您可以表示“哪个标记在开发历史中最接近某个已命名的分支”,通常是您所在的分支,HEAD。在你的问题中,这将返回标签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等为每个标签。这为您提供了HEAD上的提交数量,因为结束于v0.2的路径与HEAD后面的路径不同。

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

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

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

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

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

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

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

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

git describe --abbrev=0 --tags

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

git remote update

您可以查看一下git describe,它所做的事情与您所要求的类似。