在尝试设置我的新鱼壳提示,我最终测试了获取分支名称的方法,并测试了我是否在 git 存储库中。我发现(1) git rev-parse --abbrev-ref HEAD
,(2) git symbolic-ref HEAD | sed 's/refs\/heads\///'
和(3) git describe --contains --all HEAD
完成这个技巧就好了。
我很好奇,因为我喜欢(1),但在一个新的、未动过的(只是git init
编辑过的)存储库上,它给了我一个“致命的:”错误,而(2)按预期工作,即给我一个默认值掌握作为输出。问题是,即使出现“fatal:”错误,返回代码也是 0。这是预期的行为吗?
为了测试我是否在 git 存储库中,我最终只是测试了当前目录是否有“.git”文件夹:test -d ".git"
。这是一个基本的解决方案,但它有效,并且似乎比使用任何 git 命令都更快。
所以,我的问题是:
- 难道不应该用“fatal:”(1)返回一个不同于 0 的退出代码?如果确实是一个错误,由于我不知道 git 人员如何标准化他们的返回代码,我应该在哪里报告它?
- 我知道如果我重定向(1)使用
^ /dev/null
(对于那些不知道的人来说,^
它与 相同2>
),我不会收到错误,但它会说HEAD
而不是 master,但如果我cat .git/HEAD
,我会得到:ref: refs/heads/master
。它到底应该说什么?使用master
我只是无知和挑剔,因为它应该说?我的意思是在ed 存储库HEAD
的情况下。git init
- 在寻求良好提示的过程中,您是否实际对任何可能的解决方案进行了基准测试?
这是我用来进行基准测试的代码(针对鱼类):
set -l before (date +%s%N)
git rev-parse --abbrev-ref HEAD
set -l after (date +%s%N)
set -l elapsed_time (expr $after - $before)
echo $elapsed_time
提前致谢!
附言:这些工具是最新的 GNU 版本,我的意思是,sed
和date
。expr
如果信息太多或有些内容不合理,我很抱歉。请耐心等待。谢谢!
编辑:正如某人在答案中正确猜到的那样,整个错误是:
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
答案1
没有完全回答您的问题,但可能不仅仅是一条评论:
根据您回答中的其他评论,我认为您看到的错误是
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
发生这种情况是因为您正在一个全新的 git 存储库上进行这些测试,该存储库没有提交的工作。这不仅不是一个真正公平的测试(从定义上讲,在较大的存储库上您的表现会更差),而且几乎在所有方面都是一个极端情况。例如,按照惯例.git/HEAD
显示ref: refs/heads/master
。抛出错误是因为HEAD
不明确。您没有历史记录,因此传递给的任何值都rev-parse
将被视为相同。此外,这对我来说不会退出 0:$ git init /tmp/test && cd /tmp/test $ git rev-parse --abbrev-ref HEAD $ echo $? 128
总之,不要为这个错误烦恼。找一个大型的 android 存储库,或者可能是 linux 内核,然后在那里测试你的提示。
HEAD
不是分支。它是指向签出状态的指针。当您签出分支时,它是指向该分支的符号引用。当您处于“分离 HEAD”状态时,指针HEAD
指向提交。HEAD
使用方法 (1) 会得到返回,因为rev-parse
只是在错误中回显传递的 refspec 值。尝试使用blah
;您会看到同样的事情。我实际上还没有对解决方案进行过基准测试,但您可以尝试以下几种方法(这两种方法都用在我的 zsh 提示符中,这不是我写的,而且它们的表现都相当不错):
git rev-parse --is-inside-work-tree ;# avoids your 'test -d .git' call ref=$(git symbolic-ref HEAD 2> /dev/null) ;# grab the full refspec branch=$(echo ${ref#refs/heads/}) ;# extract the branch name