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

如何以编程方式确定当前签出的Git分支,git,bash,shell,Git,Bash,Shell,在Unix或GNU脚本环境(例如Linux发行版、Cygwin、OSX)中,确定当前在工作目录中签出哪个Git分支的最佳方法是什么? 这种技术的一个用途是自动为发布添加标签(比如svreversion将使用Subversion) 请参阅我的相关问题:以下是我的工作: git branch | sed --quiet 's/* \(.*\)/\1/p' 输出如下所示: $ git branch | sed --quiet 's/* \(.*\)/\1/p' master $ branch_na

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

这种技术的一个用途是自动为发布添加标签(比如
svreversion
将使用Subversion)

请参阅我的相关问题:

以下是我的工作:

git branch | sed --quiet 's/* \(.*\)/\1/p'
输出如下所示:

$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"

这是一个解决方案。如果将其添加到.bashrc中,它将在控制台中显示当前分支

# git branch
parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
$PS1="\$(parse_git_branch)$PS1"

然而,这是相当有限的。但是有一个很棒的项目叫做,它正是这样做的(还有更多)。

这个项目对我来说很有效。如果您想要回一个普通字符串,则
--no color
部分很重要,也可能很重要

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

正确的解决方案是在
\uu git\u ps1
中浏览一下bash提示符的does。删除所有附加项,如选择如何描述头部分离的情况,即当我们在未命名分支上时,它是:

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

branch_name=${branch_name##refs/heads/}
用于从符号引用中提取完全限定的分支名称;我们将其用于HEAD,它当前已签出分支

替代解决方案可以是:

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}
在最后一行中,我们处理头部分离的情况,使用简单的“头部”来表示这种情况


于2013年6月11日添加


2013年6月10日发布的Junio C.Hamano(git维护者)博客文章更详细地解释了原因和方法。

有人提到在bash中用不到三个任务来完成它。。。像这样凌乱的控制流怎么样:

$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"

将接受的答案改编为windows powershell:

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

如果使用的是旧的NT命令行,则可以使用以下命令:

@for /f "usebackq" %i in (`git symbolic-ref -q HEAD`) do @echo %~ni
要在批处理文件中使用,您必须将%加倍:

@for /f "usebackq" %%i in (`git symbolic-ref -q HEAD`) do @echo %%~ni

有人认为仅仅让Git描述一下您所在的分支有什么不对吗

git rev-parse --symbolic-full-name --abbrev-ref HEAD
它可以在$()中使用,并在Bash、Powershell、Perl等中轻松传递。如果您在所执行的提交上有多个分支,并且如果您当前不在某个分支上,则不会被愚弄,它只会以“HEAD”作为回复

或者,您可以使用

git symbolic-ref --short -q HEAD

这将为您提供相同的输出,但如果您分离,它将不会返回任何内容。如果您希望在分离时出现错误,那么这个方法很有用,只需删除-q即可。

这是我的解决方案,适合在PS1中使用,或者用于自动标记发布

如果您在分支机构签出,您将获得分支机构名称

如果你在一个刚开始的git项目中,你会得到“@”

如果你是无头的,那么相对于某个分支或标记,你会得到一个很好的人名,名字前面有一个“@”

如果你是无头的,而不是某个分支或标签的祖先,你只会得到短SHA1

function we_are_in_git_work_tree {
    git rev-parse --is-inside-work-tree &> /dev/null
}

function parse_git_branch {
    if we_are_in_git_work_tree
    then
    local BR=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD 2> /dev/null)
    if [ "$BR" == HEAD ]
    then
        local NM=$(git name-rev --name-only HEAD 2> /dev/null)
        if [ "$NM" != undefined ]
        then echo -n "@$NM"
        else git rev-parse --short HEAD 2> /dev/null
        fi
    else
        echo -n $BR
    fi
    fi
}

如果我们在git工作树中,您可以删除
位,如果您愿意;我只是在PS1中的另一个函数中使用它,您可以在这里完整查看:

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

$ git status | head -1 | cut -d ' ' -f 4

答案如下:

显然适用于Git 1.6.3或更高版本。

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

我发现调用git相当慢(任何子命令), 特别是更新提示。在顶级计算机(raid 1、8 gb ram、8个硬件线程)上,repo根目录内的时间在.1秒到.2秒之间,而在repo外部的时间在.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@/[^/]*$@@;
}
#/usr/bin/perl
$cwd=$ENV{PWD}#`pwd`;
chomp$cwd;
while(长度$cwd)
{
-d“$cwd/.git”和do{
-f“$cwd/.git/HEAD”和do{
在“中打开,尝试:

 git symbolic-ref --short -q HEAD
或者尝试使用
git branch
--no color
强制使用简单的纯字符串输出:

 git branch  --no-color
在正则表达式模式下(
-E
)使用grep,您可以检查字符“*”是否存在:

 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";
}
使用: 使用--cerial可提供易于解析的向后兼容输出:

git状态--branch--ceral | grep##| cut-c4-

从文件中:

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


在bash文件中,这一个对我有效

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


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

我在这里尝试最简单、最不言自明的方法:

git status | grep "On branch" | cut -c 11-

如果您使用的是gradle

```


```

如果您位于分离的磁头上(即,您已签出一个发行版),并且具有来自git状态的输出,例如

HEAD detached at v1.7.3.1
如果您想要发布版本,我们使用以下命令

git status --branch | head -n1 | tr -d 'A-Za-z: '
这将返回1.7.3.1,我们在parameters.yml(Symfony)中将其替换为


希望这有帮助:)显然,如果分支名称中有非数字,则需要更改tr命令的参数。

结果与单行变量赋值中接受的答案相同:

branch_name=$((git symbolic-ref HEAD 2>/dev/null || echo "(unnamed branch)")|cut -d/ -f3-)

哇,这太疯狂了。这正是我在.bashrc中使用的代码。我缩短了它以使用GNU-sed选项,我一直在想,这看起来不像我的代码。我很好奇,你发布的代码是从某种公开示例中获得的吗?还有+1,因为虽然我还没有测试过,但我非常确定你的答案与GNU不兼容,所以可能会在Dar上使用它win、Solaris等。这段代码来自GitHub:我只在Darwin和Ubuntu上使用过。这两个版本都可以使用。git-branch是陶瓷(用户界面)命令,它的输出不应该在脚本中使用。It-branch是陶瓷(用户界面)命令,其输出不应在脚本中使用在我的MacOS 10.6.8系统上不起作用。使用git branch是一个非常糟糕的主意。但是如果您喜欢sed,您可以做得更简单:
git status --branch | head -n1 | tr -d 'A-Za-z: '
# RevNum=`svn status -u | grep revision | tr -d 'A-Za-z: '`  # the old SVN version
RevNum=`git status --branch | head -n1 | tr -d 'A-Za-z: '` # Git (obvs)

sed -i "/^    app_version:/c\    app_version:$RevNum" app/config/parameters.yml
branch_name=$((git symbolic-ref HEAD 2>/dev/null || echo "(unnamed branch)")|cut -d/ -f3-)