在Unix或GNU脚本环境(例如Linux发行版、Cygwin、OSX)中,确定当前在工作目录中签出哪个Git分支的最佳方法是什么?
这种技术的一个用途是自动标记版本(就像svnversion对Subversion所做的那样)。
请参阅我的相关问题:如何以编程方式确定Git签出是否是标记,如果是,标记的名称是什么?
在Unix或GNU脚本环境(例如Linux发行版、Cygwin、OSX)中,确定当前在工作目录中签出哪个Git分支的最佳方法是什么?
这种技术的一个用途是自动标记版本(就像svnversion对Subversion所做的那样)。
请参阅我的相关问题:如何以编程方式确定Git签出是否是标记,如果是,标记的名称是什么?
当前回答
我是这样做的:
git branch | sed --quiet 's/* \(.*\)/\1/p'
输出如下所示:
$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
其他回答
正确的解决方案是查看contrib/completions/git-completion。Bash在__git_ps1中为Bash提示符执行此操作。删除所有额外的内容,比如选择如何描述分离的HEAD情况,即当我们在未命名的分支上时,它是:
branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)" # detached HEAD
branch_name=${branch_name##refs/heads/}
Git symbol -ref用于从符号引用中提取完全限定的分支名称;我们将它用于HEAD,它目前已签出分支。
替代方案可以是:
branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}
在最后一行中,我们处理了分离的HEAD情况,简单地使用“HEAD”来表示这种情况。
增加了11-06-2013
Junio C. Hamano (git维护者)2013年6月10日的博客文章,以编程方式检查当前分支,更详细地解释了为什么(以及如何)。
我是这样做的:
git branch | sed --quiet 's/* \(.*\)/\1/p'
输出如下所示:
$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
使用——porcelain提供了一个易于解析的向后兼容输出:
Git status——branch——porcelain | grep '##' | cut -c 4-
从文档中可以看到:
瓷格式类似于短格式,但保证不会在Git版本之间或基于用户配置以向后不兼容的方式更改。这使得它非常适合通过脚本进行解析。
https://git-scm.com/docs/git-status
我发现调用git相当慢(任何子命令), 特别是更新提示符。在顶级机器(raid 1, 8 gb ram, 8个硬件线程)上,回购根目录内的时间变化在0.1到0.2秒之间,而在回购外部的时间变化在0.2秒以上。不过,它确实运行Cygwin。
因此,为了提高速度,我写了这个脚本:
#!/usr/bin/perl
$cwd=$ENV{PWD}; #`pwd`;
chomp $cwd;
while (length $cwd)
{
-d "$cwd/.git" and do {
-f "$cwd/.git/HEAD" and do {
open IN, "<", "$cwd/.git/HEAD";
$_=<IN>;
close IN;
s@ref: refs/heads/@@;
print $_;
};
exit;
};
$cwd=~s@/[^/]*$@@;
}
可能需要一些调整。
从这个答案:https://stackoverflow.com/a/1418022/605356:
$ git rev-parse --abbrev-ref HEAD
master
显然适用于Git 1.6.3或更新版本。