如何通过编程确定当前检出的Git分支

328

2
重复?https://dev59.com/SXM_5IYBdhLWcg3wWRoF - RobertG
7
在 Git 2.22(2019 年第二季度发布)中,你可以使用更为简单的方式来获取当前分支:git branch --show-current。请参考我的这个回答 - VonC
添加 --no-color 将会给出更适合脚本的结果 git branch --no-color --show-current - Paulo Amaral
这个问题可以更好地提出。然而,它在“编程上”有所不同。也就是说,如何在shell脚本或其他代码中捕获分支名称。很乐意适当编辑。 - undefined
20个回答

347

正确的解决方案是查看contrib/completions/git-completion.bash,这个文件为bash提示符中的__git_ps1提供了支持。移除所有额外的部分,如选择如何描述分离头指针情况(例如,当我们处于未命名分支上时),它是:

branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)"     # detached HEAD

branch_name=${branch_name##refs/heads/}

git symbolic-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日的博客文章“程序化检查当前分支”更详细地解释了为什么(以及如何)。


12
不要使用cat .git/refs/heads/branch,改用git rev-parse --verify refs/heads/branch。引用可以被打包,使用cat的解决方法会失败。 - Jakub Narębski
8
给所有bash字符串艺术家的挑战:肯定有比三个变量赋值更简洁的方法吧?:-D - conny
55
这条命令可以一次性获取分支名称: git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3 请注意,不要改变原始含义。 - KiRPiCH
4
如果分支名称中包含“/”,则在该命令的末尾添加“-”,否则分支将失败。git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3-这就是你想要的。 :) - shazow
70
自 Git 1.7.10 起,您可以在使用 git-symbolic-ref 命令时指定 --short 选项,这样输出中的 refs/heads 将被移除。 - CharlesB
显示剩余12条评论

245

有人觉得直接询问Git当前所在的分支有什么问题吗?

git rev-parse --symbolic-full-name --abbrev-ref HEAD

这可以在$()中使用,并且可以轻松地在Bash、Powershell、Perl等中传递。如果您有多个分支在提交时,它不会被欺骗;如果您当前没有分支,则仅回复“HEAD”。

或者,您可以使用

git symbolic-ref --short -q HEAD

如果你处于分离状态,以下代码会产生相同的输出,但不会返回任何内容。如果你想要在分离状态下出错,只需删除“-q”即可。

将会给你相同的输出,但是如果你处于分离状态,它将不会返回任何内容。如果你想在分离状态下得到一个错误,只需删除“-q”即可。


2
抱歉,我猜测--short选项仅适用于Git 1.7.10(MSYS)。第二个选项对于1.7.9(CygWin)也不起作用。 - Michael Erickson
1
你如何将命令 git rev-parse --symbolic-full-name --abbrev-ref HEAD 放入Bash的PS1变量或Csh的提示符中? - boltup_im_coding
对于PowerShell,我只使用以下代码:function Git-GetCurrentBranch() { return (&$git rev-parse --symbolic-full-name --abbrev-ref HEAD) }其中$git是我的Git.exe路径。 - Michael Erickson
4
为什么需要使用 --symbolic-full-name 参数? - Knu

56

你可以使用git name-rev --name-only HEAD


2
如果HEAD被标记了,这将输出标记而不是分支名称。 - Charles Holbrow
2
此外,如果多个分支指向同一提交,这可能会返回错误的分支。 - itsadok

41

3
如果你处于分离头状态,它就无法工作。 - Eimantas
1
@Eimantas - 在我的系统上,它只是在分离头状态下打印“HEAD”:https://gist.github.com/johnnyutahh/2f4db5c755bc032b106b。你是否运行的 Git >= 1.6.3? - Johnny Utahh
1
我喜欢这个答案,因为它可以在旧版本的Git上工作,而不像被接受的答案那样。谢谢。 - Wildcard

28

尝试使用:

 git symbolic-ref --short -q HEAD

或者你可以尝试使用git branch命令,并使用--no-color选项来强制输出简单的纯文本字符串:

 git branch  --no-color

使用grep的正则表达式模式(-E),您可以检查字符'*'是否存在:

 git branch  --no-color  | grep -E '^\*' 

结果类似于:

* currentBranch

您可以使用以下选项:

sed 's/\*[^a-z]*//g'
cut -d ' ' -f 2
awk '{print $2}'

例如:

 git branch  --no-color  | grep -E '^\*' | sed 's/\*[^a-z]*//g'
 git branch  --no-color  | grep -E '^\*' | sed cut -d ' ' -f 2
 git branch  --no-color  | grep -E '^\*' | awk '{print $2}'

如果存在错误,您将无法使用默认值:

  cmd || echo 'defualt value';

将所有代码放进一个 Bash 函数中:

function get_branch() {
      git branch --no-color | grep -E '^\*' | awk '{print $2}' \
        || echo "default_value"
      # or
      # git symbolic-ref --short -q HEAD || echo "default_value";
}

使用:

branch_name=`get_branch`;
echo $branch_name;

10

这个在我的bash文件中运行成功。

git branch | grep '^*' | sed 's/* //'  


################bash file###################
#!/bin/bash
BRANCH=$(git branch | grep '^*' | sed 's/* //' )
echo $BRANCH

2
应该将^用引号括起来以避免被扩展,即git branch | grep '^' | sed 's/* //'。 - Mingjiang Shi
1
@MingjiangShi 感谢您的建议。我已经更新了答案。 - Muhammed Basil

10

将被接受的答案调整为 Windows PowerShell:

Split-Path -Leaf (git symbolic-ref HEAD)

7

这是我的工作内容:

git branch | sed --quiet 's/* \(.*\)/\1/p'

输出结果应该是这样的:
$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$

4
git-branch 是一个命令行界面命令(即“porcelain”),其输出不应在脚本中使用。 - Jakub Narębski
1
无法在我的MacOS 10.6.8系统上运行。 - Johnny Utahh
使用git-branch是一个非常糟糕的想法。但如果你喜欢sed,你可以更简单地完成它 :) git branch | sed -n "/\*/ s/.* // p" - the.malkolm

6
这对我很有帮助。如果你想要一个纯字符串返回,那么--no-color部分是或者可以成为重要的因素。
git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'

7
git-branch是一个用户界面命令(porcelain command),其输出不应在脚本中使用。尽管加上"--no-color"可获得额外的奖励分数。 - Jakub Narębski
当输出连接到管道时,不会产生任何颜色,请尝试:git branch | cat - Thor
1
@Thor 根据你的 git config color.branch 值... - mgalgs

5
使用 --porcelain 命令可以输出向后兼容的易于解析的结果: git status --branch --porcelain | grep '##' | cut -c 4- 根据文档说明: porcelain 格式类似于 short 格式,但是保证不会因为 Git 版本或用户配置的变化而导致不向后兼容。这使得它非常适合用于脚本解析。
参考链接:https://git-scm.com/docs/git-status

如果当前分支设置了上游分支,则它还包括上游和远程分支名称,例如:master...origin/master - gowthz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接