7

我正在寻找一个将打印符号名称的 Git 命令HEAD。我正在使用这个命令

$ git name-rev --name-only HEAD
master
$ git checkout HEAD~2
$ git name-rev --name-only HEAD
master~2

但是我注意到它不适用于新的存储库

$ git init
$ git name-rev --name-only HEAD
Could not get sha1 for HEAD. Skipping.

我找到了这个解决方法

$ git init
$ git symbolic-ref --short HEAD
master

但这不适用于较旧的提交

$ git checkout HEAD~2
$ git symbolic-ref --short HEAD
fatal: ref HEAD is not a symbolic ref

所以现在我有了这个,它涵盖了新的 repos 和旧的提交

$ git symbolic-ref -q --short HEAD || git name-rev --name-only HEAD
master

我只是想知道,这是最好的方法吗?感觉这应该可以通过一个命令来实现。

4

2 回答 2

10

你写:

我正在寻找一个将打印符号名称的 Git 命令HEAD

以下内容可能足以证明您所要求的内容并非在所有情况下都有意义,仅仅是因为HEAD可能不会明确地与一个参考相关联。继续阅读。

git name-rev做什么

git-name-rev手册页中,您可以找到以下描述:

给定一个提交,找出它相对于本地参考的位置。[...]

更具体地说,git name-rev检查是否<commit-ish>可以从任何本地引用中访问(通过按字典顺序处理它们,例如developbefore master)。

让我们检查一下

$ git name-rev --name-only <commit-ish>

在不同的情况下(--name-only旗帜在这里是偶然的,因为它的效果纯粹是装饰性的)。

HEAD未分离的情况

ifHEAD没有分离,iow ifHEAD指向一个有效的 ref(我们称它为myref),那么就没有歧义了:running

$ git name-rev --name-only HEAD

简单地输出

myref

因为myref引用明确地与HEAD. 到目前为止,一切都很好。

分离HEAD 情况

在那种情况下,事情就没有那么简单了。事实上,可能有一个或多个引用<commit-ish>可以访问,或者根本没有。

存在一个或多个此类本地引用的情况

在找到第一个这样的本地引用时,git name-rev打印一个“相对”符号引用,即表单的修订

<ref>~<n>

where<ref>代表有问题的本地参考,<n>代表生成。例如,如果HEAD直接指向作为master(master作为唯一本地引用) 的祖父母的提交,则

$ git name-rev HEAD

返回

master~2

但是请注意,如果<commit-ish>可以从多个引用中访问,则返回的那个git name-rev有点随意,因为它仅由字典顺序(命令检查本地引用)决定。

没有此类本地参考的情况

很容易想象<commit-ish>无法从任何本地参考中访问的情况。实际上,这是您可以在家中复制的一个(省略了样板标准输出):

# set things up
$ mkdir test
$ cd test
$ git init

# create a commit
$ touch README.md
$ git add README.md
$ git commit -m "add README"

# detach the HEAD (make it point directly to the tip of master, instead of to master itself)
$ git checkout $(git rev-parse master)

# create a second commit (while in detached-HEAD state)
$ printf "foo\n" > README.md
$ git commit -am "write 'foo' in README"

# attempt to find a symbolic name for HEAD 
$ git name-rev --name-only HEAD
undefined

因为提交 DAG 如下所示,

A [master]
 \
  B [HEAD]

B无法从唯一的引用 ( ) 访问提交master;因此,git name-rev放弃并简单地返回undefined

结论

因为HEAD不能保证明确地与一个参考相关联,所以你所要求的没有意义:p

于 2014-12-26T18:17:07.050 回答
5

只想为您的案例添加我的解决方案:

git symbolic-ref -q --short HEAD || git describe --all --always HEAD

这包括分支、标签、分离的头(提交)和新的存储库。但是标签将被返回tags/0.1.0,例如。

于 2014-12-29T13:00:53.933 回答