代码之家  ›  专栏  ›  技术社区  ›  JasonSmith

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

  •  249
  • JasonSmith  · 技术社区  · 15 年前

    这个问题已经有了答案:

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

    这种技术的一个用途是自动标记一个发布(比如 svnversion 与颠覆有关)。

    另请参阅我的相关问题: How to programmatically determine whether a Git checkout is a tag, and if so what is the tag name?

    20 回复  |  直到 7 年前
        1
  •  266
  •   artless-noise-bye-due2AI    12 年前

    正确的解决办法是看一眼 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,HEAD是当前已签出的分支。

    另一种解决方案可能是:

    branch_name=$(git symbolic-ref -q HEAD)
    branch_name=${branch_name##refs/heads/}
    branch_name=${branch_name:-HEAD}
    

    在最后一行中,我们处理分离的头部情况,使用简单的“头部”来表示这种情况。


    增加2013年6月11日

    Junio C.Hamano(Git Maintainer)博客帖子, Checking the current branch programatically ,从2013年6月10日起解释 为什么 (和如何)更详细。

        2
  •  176
  •   Michael Erickson    12 年前

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

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

    它可以在$()中使用,并且可以在bash、powershell、perl等中轻松传递。如果您在提交时有多个分支,并且当前不在分支上,那么它只会用“head”来回答。

    或者,您可以使用

    git symbolic-ref --short -q HEAD
    

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

        3
  •  41
  •   jonny    12 年前

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

        4
  •  33
  •   Community CDub    8 年前

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

    $ git rev-parse --abbrev-ref HEAD
    master
    

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

        5
  •  18
  •   Muhammad Hassan    7 年前

    尝试:

     git symbolic-ref --short -q HEAD
    

    或者你尝试 git branch 具有 --no-color 强制简单普通字符串输出:

     git branch  --no-color
    

    当grep处于regex模式时( -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;
    
        6
  •  9
  •   tjb    13 年前

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

    Split-Path -Leaf (git symbolic-ref HEAD)
    
        7
  •  8
  •   Muhammed Basil    9 年前

    这个在bash文件中对我有用。

    git branch | grep '^*' | sed 's/* //'  
    
    
    ################bash file###################
    #!/bin/bash
    BRANCH=$(git branch | grep '^*' | sed 's/* //' )
    echo $BRANCH
    
        8
  •  6
  •   August Lilleaas    15 年前

    这个对我有用。这个 --no-color 如果您想要回一个普通的字符串,那么部分很重要,或者可能很重要。

    git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
    
        9
  •  4
  •   JasonSmith    15 年前

    我要做的是:

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

    输出如下:

    $ git branch | sed --quiet 's/* \(.*\)/\1/p'
    master
    $
    
        10
  •  4
  •   silvansky    12 年前

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

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

    $ git branch | grep "*" | cut -d ' ' -f 2
    
        11
  •  4
  •   tonywoode    8 年前

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

    git status | grep "On branch" | cut -c 11-
    
        12
  •  2
  •   qneill Adam Burry    13 年前

    有人提到在bash中只做了不到三个任务…像这样混乱的控制流程怎么样:

    branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"
    
        13
  •  2
  •   Peter Hart Andre    13 年前

    如果使用的是旧的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
    
        14
  •  2
  •   Community CDub    8 年前

    这是我的解决方案,适用于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
    }
    

    您可以删除 if we_are_in_git_work_tree 如果您愿意,我可以在PS1的另一个函数中使用它,您可以在这里全面查看: PS1 line with git current branch and colors

        15
  •  2
  •   Tony Baguette    9 年前

    使用--chinace提供向后兼容的输出,易于分析:

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

    从文档中:

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

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

        16
  •  1
  •   ravikanth    8 年前

    如果你在使用Gealle,

    ` `

    def gitHash = new ByteArrayOutputStream()    
    project.exec {
                    commandLine 'git', 'rev-parse', '--short', 'HEAD'
                    standardOutput = gitHash
                }
    
    def gitBranch = new ByteArrayOutputStream()   
    project.exec {
                    def gitCmd = "git symbolic-ref --short -q HEAD || git branch -rq --contains "+getGitHash()+" | sed -e '2,\$d'  -e 's/\\(.*\\)\\/\\(.*\\)\$/\\2/' || echo 'master'"
                    commandLine "bash", "-c", "${gitCmd}"
                    standardOutput = gitBranch
                }
    

    ` `

        17
  •  0
  •   Damien MATHIEU    15 年前

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

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

    但这是相当有限的。但是有一个伟大的项目叫做 git sh 正是这样(以及更多)。

        18
  •  0
  •   Kenney    11 年前

    我发现调用git相当慢(任何子命令)。 特别是更新提示。时间在repo的根目录中的0.1到0.2秒之间变化,在顶级计算机(raid 1、8GBram、8个硬件线程)上,在repo之外的0.2秒以上变化。不过,它确实在运行Cygwin。

    因此,我为speed写了这个脚本:

    #!/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@/[^/]*$@@;
    }
    

    可能需要一些调整。

        19
  •  0
  •   Steve Childs    8 年前

    如果您是在一个分离的头上(即您已经签出了一个版本),并且有来自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)中将其替换为

    # 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
    

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

        20
  •  0
  •   Kim Taylor    7 年前

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

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