如何以编程方式确定当前签出的Git分支

Jas*_*ith 263 git bash shell

在Unix或GNU脚本环境(例如Linux发行版,Cygwin,OSX)中,确定当前在工作目录中检出哪个Git分支的最佳方法是什么?

这种技术的一个用途是自动标记一个版本(就像svnversionSubversion一样).

另请参阅我的相关问题:如何以编程方式确定Git结帐是否为标签,如果是,那么标签名称是什么?

Jak*_*ski 285

正确的解决方案是看看contrib/completions/git-completion.bash是否为bash提示做了__git_ps1.删除所有额外内容,例如选择如何描述分离的HEAD情况,即当我们在未命名的分支上时,它是:

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

branch_name=${branch_name##refs/heads/}
Run Code Online (Sandbox Code Playgroud)

git symbolic-ref用于从符号引用中提取完全限定的分支名称; 我们将它用于HEAD,目前已检出分支.

替代解决方案可能是:

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}
Run Code Online (Sandbox Code Playgroud)

在最后一行我们处理分离的HEAD情况,使用简单的"HEAD"来表示这种情况.


已添加11-06-2013

Junio C. Hamano(git maintainer)博客文章,从2013年6月10日起以编程方式检查当前分支,更详细地解释了为什么(和hows).

  • @conny`git symbolic-ref HEAD 2>/dev/null | cut -d"/" - f 3`应该一次性获得分支名称 (48认同)
  • 从Git 1.7.10开始,你可以为`git-symbolic-ref`指定`--short`选项,它会为你删除输出中的`refs/heads`. (46认同)
  • 不要使用`cat .git/refs/heads/branch`; 使用`git rev-parse --verify refs/heads/branch`.Refs可以**打包**,而`cat`的解决方案会失败. (10认同)
  • @ Thr4wn它删除(修剪)字符串的开头,从'$ branch_name`字符串值中删除'`refs/heads /`'.请参阅http://www.thegeekstuff.com/2010/07/bash-string-manipulation/或http://tldp.org/LDP/abs/html/string-manipulation.html (4认同)
  • 所有bash字符串艺术家面临的挑战:*当然*必须有一个很好的方法在少于三个变量赋值中执行此操作?:-D (3认同)
  • @KiRPiCH你不需要管道`git symbolic-ref`的输出来摆脱`refs/head /`部分.Git有一个命令行标志:`git symbolic-ref -q --short HEAD`可以完成这项工作.我编辑了答案以反映这一建议. (3认同)
  • @KiRPiCH在该命令的末尾添加一个`-`,否则名称中带有"/"的分支将失败.`git symbolic-ref HEAD 2>/dev/null | cut -d"/" - f 3 -`就是你想要的.:) (3认同)
  • `##`在`branch_name = $ {branch_name ## refs/heads /}中做什么? (2认同)
  • @conny LOL''bash string artists' (2认同)

Mic*_*son 195

有没有人看到Git描述你所在的分支有什么问题?

git rev-parse --symbolic-full-name --abbrev-ref HEAD
Run Code Online (Sandbox Code Playgroud)

这可以在$()中使用,并在Bash,Powershell,Perl等中轻松传递.如果您在提交中有多个分支,并且如果您当前不在分支上,那么它不会被欺骗,它只是简单的回复"HEAD".

或者,您可以使用

git symbolic-ref --short -q HEAD
Run Code Online (Sandbox Code Playgroud)

哪个会给你相同的输出,但如果你被分离,它将不会返回任何内容.如果你想在分离时发生错误,这个很有用,只需删除-q即可.

  • 对不起,我想synbolic-ref的--short选项仅在Git 1.7.10(MSYS)中可用.第二个选项对1.7.9(CygWin)也不起作用. (2认同)
  • 为什么你需要`--symbolic-full-name`? (2认同)

jon*_*nny 46

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

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

Joh*_*ahh 35

从这个答案:https://stackoverflow.com/a/1418022/605356:

$ git rev-parse --abbrev-ref HEAD
master
Run Code Online (Sandbox Code Playgroud)

显然适用于Git 1.6.3或更新版本.

  • 如果你处于分离状态,它就不起作用. (3认同)

fit*_*rec 21

试试:

 git symbolic-ref --short -q HEAD
Run Code Online (Sandbox Code Playgroud)

或者你尝试git branch--no-color武力简单的纯字符串输出:

 git branch  --no-color
Run Code Online (Sandbox Code Playgroud)

使用grep in regex mode(-E),您可以检查是否存在字符'*':

 git branch  --no-color  | grep -E '^\*' 
Run Code Online (Sandbox Code Playgroud)

结果类似于:

* currentBranch
Run Code Online (Sandbox Code Playgroud)

您可以使用以下选项:

sed 's/\*[^a-z]*//g'
cut -d ' ' -f 2
awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)

例如:

 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}'
Run Code Online (Sandbox Code Playgroud)

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

  cmd || echo 'defualt value';
Run Code Online (Sandbox Code Playgroud)

全部进入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";
}
Run Code Online (Sandbox Code Playgroud)

使用:

branch_name=`get_branch`;
echo $branch_name;
Run Code Online (Sandbox Code Playgroud)


tjb*_*tjb 10

使接受的答案适应windows powershell:

Split-Path -Leaf (git symbolic-ref HEAD)
Run Code Online (Sandbox Code Playgroud)


muh*_*sil 9

这个在bash文件中为我工作.

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


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

  • ^* 应该被引用以避免被扩展,即 git branch | grep '^*' | sed 's/* //' (2认同)

Jas*_*ith 6

这是我所做的:

git branch | sed --quiet 's/* \(.*\)/\1/p'
Run Code Online (Sandbox Code Playgroud)

输出将如下所示:

$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
Run Code Online (Sandbox Code Playgroud)

  • git-branch 是 *porcelain*(用户界面)命令,其输出不应在脚本中使用 (4认同)

Aug*_*aas 6

这个对我有用.--no-color如果你想要一个普通的字符串,这部分是或者可能是重要的.

git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
Run Code Online (Sandbox Code Playgroud)

  • git-branch是*porcelain*(用户界面)命令,其输出不应该在脚本中使用.虽然你得到'--no-color'的奖励积分. (7认同)

sil*_*sky 5

我发现了两种非常简单的方法:

$ git status | head -1 | cut -d ' ' -f 4
Run Code Online (Sandbox Code Playgroud)

$ git branch | grep "*" | cut -d ' ' -f 2
Run Code Online (Sandbox Code Playgroud)


Ton*_*tte 5

使用 --porcelain 可以提供易于解析的向后兼容的输出:

git status --branch --porcelain | grep '##' | cut -c 4-

从文档中:

瓷器格式与短格式类似,但保证不会在 Git 版本之间或基于用户配置以向后不兼容的方式进行更改。这使得它非常适合通过脚本进行解析。

https://git-scm.com/docs/git-status


ton*_*ode 5

我正在尝试最简单,最容易解释的方法:

git status | grep "On branch" | cut -c 11-
Run Code Online (Sandbox Code Playgroud)