commit1-----tagA,tagB
git checkout tagA
问题:如何获取当前结帐的代码名称?我试过git describe
,但它总是返回名称“tagB”,期望返回“tagA”。
似乎git describe
只能返回最新的标记名称,请参阅git manual
该命令查找可从提交访问的最新标记。 如果标记指向提交,则仅显示标记。 否则,它将标签名称后缀为附加数量 提交在标记对象和缩写对象名称之上 最近的提交。
还有其他方法吗?
目的与此问题相关:
我想让文件自动构建标签名称的版本号,{1}}在1提交1个标签时运行良好,但在上述情况下它没用。
答案 0 :(得分:3)
tagA
和tagB
都指向一个特定的提交,因此就git而言,如果要查看或查看该名称,则其中一个名称同样好(或同样差)特别提交。
文档的短语"最新标记"这可能会误导(虽然这可能是你输出tagB
的原因。)
如果你想知道你给git checkout
的标记名称,你可以自己保存,或者查阅HEAD
的reflog:
8004647 HEAD@{0}: checkout: moving from master to v2.3.1
reflog方法的优点是它已经实现了;但是reflogs只会保留一段时间(可配置,默认90天可达参考),然后过期以防止reflogs永远增长。
"最近"意味着如果标签具有关联的日期和时间标记 - 带标注的标签,那么轻量级标签就不会 - 那些具有较晚时间的标签被认为是#34;更好",如下所述。
请注意,任何时候,任何git命令都可以轻松查找所有外部引用并将它们转换为SHA-1。要查看其工作原理,只需运行git for-each-ref
(您可能希望将其传输到类似less
的寻呼机)。输出看起来像这样:
c2e8e4b9da4d007b15faa2e3d407b2fd279f0572 commit refs/heads/maint
9ab698f4000a736864c41f57fbae1e021ac27799 commit refs/heads/master
[snip]
74d2a8cf12bf102a8cedaf66736503bb3fe88dfb tag refs/tags/v2.2.0
[more snippage]
这些是分支和标签 - 在这个git存储库中(对于git本身)所有标签都有注释 - 以及它们对应的SHA-1。如果存在活动存储,它也会显示(在refs/stash
下)。
在任何情况下,假设git describe
此时具有其中一个提交ID(SHA-1),describe
也找到了两个或多个解析为该ID的名称。这些可能只是带注释的标签名称,这是您没有选项的结果,或者它们可能是--all
允许的另一个名称(如分支名称);但重要的是假设有两个或更多名称,都指向同一个提交。
describe
命令可以尝试记住所有这些名称,但它并没有。相反,它通过一种两次一次的比赛来运行名称,以查看哪一个赢得比赛":
git describe
应该使用的。一旦这个提交的所有名称都相互竞争,选择一个赢得名字","获胜名称"与提交SHA-1一起保存。
现在,我们如何首先获得该提交ID?答案是git describe
从你的论点开始:
$ git describe # no args, means ...
$ git describe HEAD # use HEAD to get the SHA-1
您的参数(或HEAD
)使用git rev-parse
转换为适当的原始SHA-1(嗯,其C代码等效):
$ git rev-parse HEAD
9ab698f4000a736864c41f57fbae1e021ac27799
然后,git describe
调用git for-each-ref
(或其等效的C代码)将您允许使用的所有名称(默认情况下,所有带注释的标记)转换为SHA-1 ID。如果其中任何一个与此 SHA-1匹配,则会保存它们。如果有多场比赛,他们会通过比赛选出一名获胜者。
对于您的特定情况,此部分成功:tagA
和tagB
都是完全匹配,因此在选择这两者之间的获胜标记后,整个事情就会停止。在你的情况下,你没有想要的标签。
一般而言,git describe
通常必须坚持下去。例如,考虑git
项目本身的以下提交:
088c9a8 strbuf.h: format asciidoc code blocks as 4-space indent
aa07cac strbuf.h: drop asciidoc list formatting from API docs
6afbbdd strbuf.h: unify documentation comments beginnings
bdfdaa4 strbuf.h: integrate api-strbuf.txt documentation
eae6953 tests: correct misuses of POSIXPERM
1767c51 t/lib-httpd: switch SANITY check for NOT_ROOT
b4a56a3 "log --pretty" documentation: do not forget "tformat:"
现在假设我们创建一个标记X
指向提交b4a56a3
,一个标记Y
指向提交eae6953
,并且一个标记Z
指向提交aa07cac
。如果我们再问git"描述"提交088c9a8
,可以将其描述为以下任何一种:
X
或Y
或Z
git describe
的输出将使用标记Z
,因为它需要更少的步骤来标记Z" (提交aa07cac
)到有问题的提交(088c9a8
)。这实际上是如何发生的(可能是不必要的,虽然这是一个价值判断:-))复杂。
这里git describe
的作用是遍历(部分)提交图(如果指定则应用--first-parent
)以找到附近的""具有名称的提交。搜索顺序有点难以描述:它部分基于日期(la git log
的日期排序提交列表),但如果它遇到带注释的标签则会提前停止。否则它会累积一个"候选名称列表" (使用上述竞赛方法),当累积了足够的(默认10个)候选名称时停止,然后对列表进行排序。排序基于"图形距离",因此假设X
,Y
和Z
都是轻量级标记 - 如果有任何标注标记,则它应该是现在被选中并且搜索停止了 - Z
在这里获胜。
最后,找到一个指向合适提交的名称,该提交实际上不是作为参数的给定提交,git describe
打印名称,远离步数("深度" ),以及g
和实际SHA-1的一部分:
v2.3.3-220-g9ab698f
(虽然深度和g
可以被抑制,如果根本找不到任何名字或者你只是要求完全匹配,整个事情都可能失败,等等。 / p>
答案 1 :(得分:2)
您至少可以获得给定提交的所有标记:
git tag --points-at HEAD
--points-at <object>
仅列出给定对象的标签。
从那里,你可以提取你想要的那个。