如何以编程方式确定Git签出是否为标记,如果是,则标记名称是什么

Jas*_*ith 47 git bash shell

在Unix或GNU脚本环境(例如Linux发行版,Cygwin,OSX)中,确定当前结帐是否为Git标记的最佳方法是什么.如果是标签,我该如何确定标签名称?

这种技术的一个用途是自动标记一个版本(就像svnversionSubversion一样).

请参阅我关于以编程方式检测Git分支的相关问题.

Jak*_*ski 56

您的问题的解决方案是使用

git describe --exact-match HEAD
Run Code Online (Sandbox Code Playgroud)

(它只考虑带注释的标签,但你应该使用带注释的,甚至可能是带签名的标签来标记版本).

如果要考虑所有标记,还要考虑轻量级标记(通常用于本地标记),可以使用以下--tags选项:

git describe --exact-match --tags HEAD
Run Code Online (Sandbox Code Playgroud)

但我认为你在这里有" XY问题 ",因为你问的是问题的可能解决方案,而不是问一个问题的问题......这可以有更好的解决方案.

您的问题的解决方案是看看Git如何在GIT-VERSION-GEN脚本中执行它,以及它如何在其Makefile中使用它.

  • 雅各布充分尊重你对我的发布过程的建议,以及你对我的真实问题的猜测,都是无关紧要的.但是,感谢您的技术解决方案. (2认同)

Jas*_*ith 5

更好的解决方案(来自 Greg Hewgill 在另一个问题中的回答)是:

git name-rev --name-only --tags HEAD
Run Code Online (Sandbox Code Playgroud)

如果它返回“undefined”,那么你就不是一个标签。否则它返回标签名称。因此,像我的其他答案一样做一些事情的单行代码是:

git_tag=`git name-rev --name-only --tags HEAD | sed 's/^undefined$//'`
Run Code Online (Sandbox Code Playgroud)

其工作原理的交互式 shell 示例:

$ git checkout master
Already on "master"
$ git name-rev --name-only --tags HEAD
undefined
$ git checkout some-tag
Note: moving to "some-tag" which isnt a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 1234567... Some comment blah blah
$ git name-rev --name-only --tags HEAD
some-tag
Run Code Online (Sandbox Code Playgroud)

  • 如果 HEAD 是 **reachable** from tag(例如,通过某个其他分支提前到当前签出的分支),这将无法正常工作,但它不在标签本身上。你会得到这样的结果:“some-tag~3” (2认同)

Gre*_*ill 5

执行此操作的最佳方法是使用以下git describe命令:

git-describe - 显示可以从提交中访问的最新标记

该命令查找可从提交访问的最新标记.如果标记指向提交,则仅显示标记.否则,它将标记名称后缀为标记对象顶部的附加提交数和最近提交的缩写对象名称.


Tux*_*ude 5

的使用GIT-名称-REV是优选的脚本,因为它是GIT中的一部分的管道,而GIT-描述是部分

如果 HEAD 指向 1,则使用此命令打印标签的名称,否则不打印。

git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed -n 's/^\([^^~]\{1,\}\)\(\^0\)\{0,1\}$/\1/p'
Run Code Online (Sandbox Code Playgroud)

请注意将 stderr 重定向到 /dev/null - 否则您将收到一条错误消息:

fatal: cannot describe 'SOMESHA'"
Run Code Online (Sandbox Code Playgroud)

编辑:修复了 sed 中的正则表达式以支持轻量级和带注释/签名的标签。


Rob*_*mer 5

您无法确定当前结帐是否“是标签”。您只能确定当前结帐是否是具有标签的提交。

不同之处在于:如果有多个标签指向这个 commit,git 无法告诉你你曾经使用过哪个结账,也无法告诉你是否真的使用了一个来到达那里。

Jakub 在这里基于的答案git describe --exact-match (--tags)为您提供了所有(带注释的)标签中的“第一个”

git describe像这样对它们进行排序:

  • 首先注释标签
    • 先排序最年轻
  • 轻量级标签随后出现
    • 按标签名称排序的二进制(如果它是用 ASCII 编码的英文,则意味着按字母顺序)
    • git 不存储带有轻量标签的元数据,因此无法实现“年轻优先”