development

현재 체크 아웃 된 Git 브랜치를 프로그래밍 방식으로 결정하는 방법

big-blog 2020. 4. 1. 08:02
반응형

현재 체크 아웃 된 Git 브랜치를 프로그래밍 방식으로 결정하는 방법


이 질문에는 이미 답변이 있습니다.

Unix 또는 GNU 스크립팅 환경 (예 : Linux 배포판, Cygwin, OSX)에서 현재 Git 브랜치를 작업 디렉토리에서 체크 아웃하는 가장 좋은 방법은 무엇입니까?

이 기술의 한 가지 사용은 svnversionSubversion에서와 같이 릴리스에 자동으로 레이블을 지정하는 것입니다.

또한 관련 질문 : Git 체크 아웃이 태그인지 프로그래밍 방식으로 결정하는 방법과 태그 이름이 무엇인지 확인하십시오.


올바른 해결책은 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/}

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 maintenanceer) 블로그 게시물 ( 2013 년 6 월 10 일부터 프로그래밍 방식으로 현재 지점 확인 )에 대한 자세한 내용과 이유를 설명합니다 .


누군가 Git에게 당신이있는 지점을 설명하도록 요청하는 데 문제가 있습니까?

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

$ () 내에서 사용할 수 있으며 Bash, Powershell, Perl 등에서 쉽게 전달할 수 있습니다. 커밋에 여러 가지가 있고 현재 브랜치에 있지 않은 경우 속지 않습니다. "HEAD"로 응답합니다.

또는 사용할 수 있습니다

git symbolic-ref --short -q HEAD

동일한 출력을 제공하지만 분리 된 경우 아무것도 반환하지 않습니다. 분리 할 때 오류가 발생하면 -q를 제거하십시오.


당신이 사용할 수있는 git name-rev --name-only HEAD


이 답변에서 https://stackoverflow.com/a/1418022/605356 :

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

분명히 Git 1.6.3 이상에서 작동합니다.


시도해보십시오 :

 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";
}

사용하다:

branch_name=`get_branch`;
echo $branch_name;

허용 된 답변을 Windows Powershell에 적용 :

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

이것은 bash 파일에서 나를 위해 일했습니다.

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


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

이것은 나를 위해 작동합니다. --no-color일반 문자열을 다시 원한다면 부분은 중요하거나 중요 할 수 있습니다.

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

나는 여기서 가장 간단하고 가장 자명 한 방법을 시도하고 있습니다.

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

여기 내가하는 일이 있습니다.

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

결과는 다음과 같습니다.

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

나는 그것을하는 두 가지 간단한 방법을 발견했다.

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

$ git branch | grep "*" | cut -d ' ' -f 2

누군가 3 배 미만으로 배쉬에서 그것을 언급했다고 언급했습니다 ... 어떻게 지저분한 제어 흐름은 다음과 같습니다.

branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo 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

다음은 PS1에서 사용하거나 릴리스 자동 레이블링에 적합한 솔루션입니다.

지점에서 체크 아웃하면 지점 이름을 얻습니다.

당신이 단지 init'd 자식 프로젝트에 있다면, 당신은 단지 '@'를 얻는다.

머리가없는 경우 이름 앞에 '@'가 붙은 일부 브랜치 또는 태그와 관련하여 좋은 사람 이름을 얻습니다.

머리가없고 일부 브랜치 또는 태그의 조상이 아닌 경우 짧은 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의 다른 함수에서 사용하면 여기에서 전체를 볼 수 있습니다 : git current branch 및 색상이있는 PS1 라인


--porcelain을 사용하면 이전 버전과 호환되는 출력을 쉽게 구문 분석 할 수 있습니다.

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

설명서에서 :

도자기 형식은 짧은 형식과 비슷하지만 Git 버전간에 또는 사용자 구성에 따라 이전 버전과 호환되지 않는 방식으로 변경되지는 않습니다. 따라서 스크립트로 구문 분석하는 데 이상적입니다.

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


gradle을 사용하는 경우

```

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
            }

```


한 줄 변수 할당에서 허용되는 답변과 동일한 결과 :

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

그게 하나의 해결책입니다. .bashrc에 추가하면 콘솔에 현재 분기가 표시됩니다.

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

그러나 꽤 제한적입니다. 그러나 git sh 라는 훌륭한 프로젝트가 있습니다.이 프로젝트 는 정확히 그 이상을 수행합니다.


git 호출은 특히 프롬프트를 업데이트하는 데 다소 느립니다 (하위 명령 중 하나). 시간은 리포지토리의 루트 디렉토리 내에서 .1 초와 .2 초 사이이며, 최상위 노치 머신 (레이드 1, 8GB 램, 8 하드웨어 스레드)에서 리포지토리 외부에서 .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@/[^/]*$@@;
}

약간의 조정이 필요할 수 있습니다.


분리 된 헤드에 있고 (즉, 릴리스를 체크 아웃 한 경우) 다음과 같은 자식 상태에서 출력이있는 경우

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 명령의 인수를 변경해야합니다.

참고 URL : https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch


반응형