현재 디렉토리가 Git 저장소인지 확인


198

zsh에서 Git 관리를위한 일련의 스크립트를 작성하고 있습니다.

현재 디렉토리가 Git 저장소인지 어떻게 확인합니까? (Git 리포지토리에 있지 않을 때는 많은 명령을 실행하고 많은 fatal: Not a git repository응답을 얻고 싶지 않습니다 ).


영감을 얻기 위해 bash 완성 파일 (contrib / completion / git-completion.bash)을 보셨습니까? 내 bash 프롬프트의 일부로 __git_ps1 명령을 사용합니다. 실제로 대부분은 zsh 내에서 제공됩니다. __gitdir 함수는 아마도 당신이 원하는 것입니다.
jabbie

1
@jabbie : 왜 대답하지 않습니까?
마릴리온

zsh 배포에서 이미 기능을 확인 했습니까?
MBO


1
참고 : 현재 답변 중 어느 것도 환경 변수 $GIT_DIR또는 $GIT_WORK_TREE환경 변수를 고려하지 않습니다 .
o11c

답변:


154

bash 완성 파일에서 복사 한 다음은 순진한 방법입니다.

# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
# Distributed under the GNU General Public License, version 2.0.

if [ -d .git ]; then
  echo .git;
else
  git rev-parse --git-dir 2> /dev/null;
fi;

함수로 감싸거나 스크립트에서 사용할 수 있습니다.

bashzsh에 적합한 한 줄 조건으로 압축

[ -d .git ] && echo .git || git rev-parse --git-dir > /dev/null 2>&1

3
@William Pursell 왜 필요 없을 때 포크? 사소한 경우에 주로 속도.
jabbie February

16
를 사용하려면 답변을 업데이트해야합니다 git rev-parse --is-inside-git-dir. git rev-parse --is-inside-work-treePS1을 설정하기 전에 개인적으로 사용 합니다.
juliohm

12
@juliohm --is-inside-git-dir은 실제로 저장소 의 .git디렉토리 안에있는 경우에만 true를 반환 합니다. 나는 OP가 그것을 찾고 있다고 생각하지 않습니다.
nyuszika7h

7
git repo 외부에있을 때도 작동 하지 --is-inside-work-tree않습니다 --is-inside-git-dir. 참조 : groups.google.com/forum/#!topic/git-users/dWc23LFhWxE
fisherwebdev

7
git 디렉토리가 아닌 다른 디렉토리라면 실패합니다 .git. 견고성을 위해를 생략하고 [ -d .git ]사용하십시오 git rev-parse ....
피터 존 Acklam

134

당신이 사용할 수있는:

git rev-parse --is-inside-work-tree

git repos 작업 트리에 있으면 'true'로 인쇄됩니다.

자식 저장소 외부에 있고 'false'를 인쇄하지 않으면 여전히 STDERR로 출력을 반환합니다.

이 답변에서 가져온 것 : https : //.com/a/2044714/12983


확인하는 가장 간단한 방법입니다.
calbertts

3
이것은 작동 트리가없는 베어 리포지토리의 경우 여전히 거짓을 인쇄합니다.
noggin182

하위 디렉토리는 고려하지 않습니다. 확인 git rev-parse --show-toplevel중인 하위 폴더와 일치 하는지 확인해야합니다.
alper

선택한 답변은 아무것도 인쇄하지 않았습니다. 이것은 효과가 있었다.
ScottyBlades

48

git rev-parse --git-dir 사용

만약 git rev-parse --git-dir> / dev / null 2> & 1; 그때
  : # 이것은 유효한 자식 저장소입니다.
    # 디렉토리가 최상위 레벨이 아닐 수 있습니다.
    # 관심이 있다면 git rev-parse 명령의 출력을 확인하십시오)
그밖에
  : # 이것은 git 저장소가 아닙니다.
fi


7

공개적으로 액세스 가능하거나 문서화 된 방법이 있는지 확실하지 않습니다 (git 소스 자체에서 사용 / 남용 할 수있는 내부 git 함수가 있습니다)

당신은 같은 것을 할 수 있습니다;

if ! git ls-files >& /dev/null; then
  echo "not in git"
fi

7

@Alex Cory의 답변을 바탕으로 :

[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]

중복 작업을 포함하지 않으며 -e모드 에서 작동 합니다.

  • @ go2null이 지적했듯이 이것은 베어 리포지토리 에서 작동하지 않습니다. 어떤 이유로 든 베어 리포지토리로 작업하려는 경우 git rev-parse출력을 무시하고 성공 여부 만 확인할 수 있습니다 .
    • 위의 줄은 스크립팅을 위해 압축되어 있으며 사실상 모든 git명령은 작업 트리 내에서만 유효 하기 때문에이 단점을 고려하지 않습니다 . 따라서 스크립팅 목적으로 "git repo"내부가 아닌 작업 트리 내부에 관심이있을 것입니다.

이 베어 자식의 repo의 내부 실패
go2null

출력을 확인하는 대신 반환 값을 확인하는 것이 좋습니다. 전혀 호출하지 마십시오 [. 그냥 이렇게 if git rev-parse --is-inside-work-tree; then ...(원하는대로 리디렉션으로.)
윌리엄 Pursell

1
@WilliamPursell는 종료 값을 확인 여기에 작동하지 않습니다 stackoverflow.com/questions/2180270/...
ivan_pozdeev

@Ivan_pozdeev "작업"의 정의에 따라 다릅니다. 이 경우 반환 값을 확인하면 작동하지만 출력 확인은 작동하지 않습니다. 두 경우 모두 쉘에서 코드를 작성하는 최상의 방법의 관점에서 리턴 값을 확인하는 것이 더 적절합니다.
William Pursell

@WilliamPursell 당신이 링크 된 주석을 읽으면, 여기서 "작동하지 않는다"는 것이 무엇을 의미하는지 알게 될 것입니다.
ivan_pozdeev

6

다른 해결책은 명령의 종료 코드를 확인하는 것입니다.

git rev-parse 2> /dev/null; [ $? == 0 ] && echo 1

git repository 폴더에 있으면 1이 인쇄됩니다.


.git디렉토리 내부에 있어도 rc 0을 가질 수 있습니다.
ivan_pozdeev 1

Git은 엉뚱하게 작성되었으므로 원하지 않는 파일을 닫을 수 있습니다 git rev-parse 2>&-.
jthill

3

이 답변은 샘플 POSIX 셸 함수와 @ jabbie 's answer 를 보완하는 사용 예제를 제공합니다 .

is_inside_git_repo() {
    git rev-parse --is-inside-work-tree >/dev/null 2>&1
}

git0git 저장소 내에 있으면 errorlevel을 반환하고, 그렇지 않으면 errorlevel을 반환합니다 128. (또한 반환 true되거나 falsegit 저장소 내에있는 경우)

사용 예

for repo in *; do
    # skip files
    [ -d "$repo" ] || continue
    # run commands in subshell so each loop starts in the current dir
    (
        cd "$repo"
        # skip plain directories
        is_inside_git_repo || continue
        printf '== %s ==\n' "$repo"
        git remote update --prune 'origin' # example command
        # other commands here
    )
done

충분치 않은. 내부 .git에서는 성공하지만 인쇄 할 것 false입니다.
ivan_pozdeev

@ivan_pozdeev : 경우 git rev-parse --is-inside-work-tree반환 true또는 false다음이 있다 힘내의 repo 내에서, 그 어떤 함수가 반환됩니다. 즉, 기능이 정확합니다
go2null

확장하려면 답변의 설명을 참조하십시오 .git에서 반환 된 값은 무시되고 오류 수준이 사용됩니다.
go2null

2

이것은 나를 위해 작동합니다. 여전히 오류가 발생하지만 쉽게 억제 할 수 있습니다. 하위 폴더 내에서도 작동합니다!

자식 상태> / dev / null 2> & 1 && echo Hello World!

조건부로 더 많은 작업을 수행해야하는 경우이를 if then 문에 넣을 수 있습니다.


2
아마도 많은 경우에 충분하지만 베어 git repo에서는 실패합니다.
와일드 카드

3
git status큰 / 오래된 레포에서 매우 느려질 수 있습니다. 나는 이것을 목적으로 사용하지 않을 것입니다.
henrebotha

1

종료 코드를 사용하지 않는 이유는 무엇입니까? 자식 저장소는 현재 디렉토리에있는 경우, 다음 git branchgit tag명령 0의 종료 코드를 반환; 그렇지 않으면 0이 아닌 종료 코드가 리턴됩니다. 이런 식으로 git 저장소가 존재하는지 여부를 결정할 수 있습니다. 간단히 다음을 실행할 수 있습니다.

git tag > /dev/null 2>&1 && [ $? -eq 0 ]

이점 : Flexibe. 베어 및 비 베어 리포지토리와 sh, zsh 및 bash에서 모두 작동합니다.

설명

  1. git tag: 존재 여부를 판별하기 위해 저장소의 태그 가져 오기
  2. > /dev/null 2>&1: 정상 및 오류 출력을 포함하여 아무것도 인쇄하지 않습니다.
  3. [ $? -eq 0 ]: 이전 명령이 종료 코드 0으로 리턴되었는지 확인하십시오. 아시다시피, 0이 아닌 모든 종료는 잘못된 일이 발생했음을 의미합니다. $?이전 명령의 종료 코드를 가져오고 [, -eq]비교를 수행합니다.

예를 들어, check-git-repo다음 내용으로 이름이 지정된 파일을 작성 하고 실행 가능하게하여 실행할 수 있습니다.

#!/bin/sh

if git tag > /dev/null 2>&1 && [ $? -eq 0 ]; then
    echo "Repository exists!";
else
    echo "No repository here.";
fi

0

# git repo인지 확인

if [ $(git rev-parse --is-inside-work-tree) = true ]; then
    echo "yes, is a git repo"
    git pull
else
    echo "no, is not a git repo"
    git clone url --depth 1
fi

이것은 모범 사례가 아닙니다. 작업 디렉토리 외부에서 실행하면 stderr에 "치명적 : git 저장소 (또는 상위 디렉토리가 아님) : .git"이 표시되고 stdout에서 "no, is a git repo"가 표시됩니다. 여기에서 전혀 호출 할 필요가 없습니다 [. 그냥 할 :if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
윌리엄 Pursell

제 경우에는 이것에 익숙하며 로그에서이 결함을 추적하고 싶습니다. 건배!
Pascal Andy

0
if ! [[ $(pwd) = *.git/* || $(pwd) = *.git ]]; then 
  if type -P git >/dev/null; then
    ! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
     printf '\n%s\n\n' "GIT repository detected." && git status
    }
  fi
fi

ivan_pozdeev 감사합니다 . 이제 .git 디렉토리 내부에서 코드가 실행되지 않아 오류가 인쇄되지 않거나 잘못된 종료 상태가 아닌지 테스트합니다.

" ! [[$ (pwd) = .git / || $ (pwd) = * .git]] "는 .git 저장소에 있지 않은 경우 git 명령을 실행합니다. 내장 유형 명령은 git이 설치되어 있는지 또는 PATH 내에 있는지 확인하는 데 사용됩니다. 도움말 유형을 참조하십시오


0

어때요?

if git status -s 2>/dev/null;then
    echo "this is a git repo"
else
    echo "this is NOT a git repo"
fi

-1

zshrc의 $ PS1을 하나 이상의 다른 git-prompt 도구로 추가하거나 교체 할 수 있습니다 . 이런 식으로 git repo에 있는지 repo의 상태에 있는지 편리하게 알 수 있습니다.


3
OP의 전체 질문은 스크립트 내에서 어떻게해야하는지
Andrew C

스크립트 내에서 __git_ps1을 어떻게 사용할 수 없습니까? git-prompt의 요점은 현재 디렉토리의 git 상태를 확인하는 것입니다.
jxqz

-1
! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { 
  printf '%s\n\n' "GIT repository detected." && git status
}

! git repo가 ​​아닌 디렉토리에서 이것을 실행하더라도 치명적인 오류는 발생하지 않습니다.

>을 / dev / null 2> & 1 메시지를 전송하는 을 / dev / null 당신은 종료 상태 쫓고 있기 때문이다. 는 {} 애프터 모든 명령 때문에 명령 그룹에 대한 있습니다 || 우리가!를 사용한 이후 git rev-parse가 성공하면 실행됩니다! git rev-parse의 종료 상태를 무효화했습니다. 의 printf는 단지 REPO의 상태를 인쇄 할 몇 가지 메시지와 자식 상태를 인쇄하는 것입니다.

함수로 감싸거나 스크립트에 넣으십시오. 도움이 되었기를 바랍니다


1
충분치 않은. 내부 .git에서는 성공하지만 인쇄 할 것 false입니다.
ivan_pozdeev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.