ChatGPT解决这个技术问题 Extra ChatGPT

显示你在哪个 git 标签上?

我无法找出当前签出的标签。

当我做:

git checkout tag1
git branch

我似乎无法找出我在哪个标签上。它只记录:

* (no branch)
master

是否可以找出签出的标签?在上面的示例中,这将是 tag1


T
Tim

编辑:Jakub Narębski 有更多的 git-fu。以下更简单的命令可以完美运行:

git describe --tags

(或者如果您已签出带注释的标签,则没有 --tags。我的标签是轻量级的,所以我需要 --tags。)

原答案如下:

git describe --exact-match --tags $(git log -n1 --pretty='%h')

拥有更多 git-fu 的人可能有更优雅的解决方案......

这利用了 git-log 从您签出的内容开始报告日志这一事实。 %h 打印缩写散列。然后 git describe --exact-match --tags 找到与该提交完全匹配的标签(轻量级或带注释的)。

上面的 $() 语法假定您使用的是 bash 或类似的。


如果您正好在(带注释的)标签上,则仅使用 git describe 将显示标签名称,如果不是,则使用 <tag>-<n>-g<shortened sha-1>,其中 <n> 是自 <tag> 以来的提交数。
@Jakub - 谢谢。在您发表评论前几秒钟,我在答案中添加了 --exact-match。很高兴知道您可以删除它并仍然从模糊输入中获得良好的信息。
谢谢,这正是我想要的。顺便说一句,即使 git-describe --exact-match(没有 --tags)也适合我。
使用 git rev-parse HEAD 是比 git log -n1 --pretty='%h' 更好的解决方案...但是为什么不能简单地写 HEAD(或者什么都不写,因为 git describe 默认为 HEAD)?
只有 Guybrush 讨厌瓷器
M
M K

这对我有用git describe --tags --abbrev=0

编辑 2020:正如下面的一些评论所提到的,这可能对你有用,也可能对你不起作用,所以要小心!


是的。即使您不完全在该标签上,这也有效! :)
呃。 ...如果您在标签之后签出哈希三个提交,那么您就不是“在那个标签上”。它会告诉您在签出提交之前或提交时的最后一个标签。所以这是不正确的。
也适用于 Windows :)
--exact-match 添加到此答案以仅查看当前提交的标记。
G
George Pavelka

显示当前 HEAD(或提交)上的所有标签

git tag --points-at HEAD

请注意,即使结果为空,此命令也不会在命令行报告错误。漏洞?如果该位置有多个标签,它还会返回一个列表。这是最好的答案,但脚本编写者应谨慎行事,牢记这些警告。
关注@ingyhere 的评论。是的,它没有错误是很好的信息,人们需要相应地处理结果。但我不会称其为错误。就我而言,“如果没有标签则为空”是有效的。其他情况下,有人可以将其保存到变量然后 check if it is empty (link to bash instructions)
这意味着没有指向当前 HEAD 的标签。
D
Daniel Serodio

git describe 是一个 porcelain 命令,您应该避免:

http://git-blame.blogspot.com/2013/06/checking-current-branch-programatically.html

相反,我使用了:

git name-rev --tags --name-only $(git rev-parse HEAD)

它返回“未定义”
这为对应于标签的提交输出一个尾随 ^0(例如,对于标签 1.0,它输出 1.0^0)。有没有办法让 Git 只输出 1.0,或者我应该为此使用 sed 吗?
只是一些概念上的吹毛求疵:我认为你颠倒了瓷器和管道的含义。可以使用瓷器,它是高级别的,适用于normal use。 Plumbing ist internal(顾名思义),只是不推荐,因为 git 开发人员保留在不发出警告的情况下更改其参数和输出的权利。所以你的第一个建议实际上是稍微更合适的建议。
链接的文章说要避免使用“git branch”,因为它不适用于这个用例。我想不出任何避免使用 git describe 的充分理由。就像 Leo 所说,“Porcelain”命令是您通常应该使用的命令。除非您真的知道自己在做什么,否则请避免使用管道命令。 “git describe”效果很好。
“瓷器”命令是您应该使用的命令,而不是您应该避免的命令。它们是其输出是机器可读的命令,并且在未来的版本中不会改变,因此可以在脚本等中依赖。非瓷器命令往往会产生更多人类可读的输出,但它可能会在未来的版本中改变,例如使其更多可读,而不是因为重要的东西实际上已经改变了。
m
mipadi

当您签出一个标签时,您会得到一个称为 "detached head" 的东西。通常,Git 的 HEAD 提交是指向您当前已签出的分支的指针。但是,如果您检查的不是本地分支(例如,标记或远程分支),那么您有一个“分离的头”——您实际上并不在任何分支上。你不应该在一个分离的头上进行任何提交。

如果您不想进行任何编辑,可以查看标签。如果您只是检查文件的内容,或者您想从标签构建您的项目,那么可以git checkout my_tag 处理这些文件,只要您不进行任何提交。如果你想开始修改文件,你应该基于标签创建一个分支:

$ git checkout -b my_tag_branch my_tag

将从 my_tag 开始创建一个名为 my_tag_branch 的新分支。在此分支上提交更改是安全的。


很棒的答案。
c
chriswatrous

git log --decorate

这将告诉您哪些 refs 指向当前签出的提交。


s
snazzybouche

对于一组特定的用例,这是一个有趣的例子。如果您的存储库有 v1.0.0v1.1.0v1.1.1 等版本,以及 v1 等指向最新 v1.x.x 的简写版本,以下将为您提供当前版本的参考-checked-out 提交与最新的完全版本化标签相关,如果这不起作用,则使用后备:

git describe --tags --exact-match --match "v*.*.*" \
  || git describe --match "v*.*.*" --tags \
  || git describe --tags \
  || git rev-parse HEAD

因此,假设您有以下提交:

* 4444444 (main, origin/main, tag: v2.0.0, tag: v2.0, tag: v2)
* 3333333
* 2222222 (tag: v1.1.0, tag: v1.1, tag: v1)
* 1111111 (tag: v1.0.0, tag: v1.0)
* 0000000

上面命令的一些示例 HEAD 的输出:

git checkout main -> v2.0.0

git checkout 3333333 -> v1.1.0-1-g3333333

git checkout 2222222 -> v1.1.0

git checkout v1 -> v1.1.0

git checkout 0000000 -> 0000000(完整参考)