고쳐 쓰다

고쳐 쓰다

zsh셸 에서는 git저장소 내에 있는지 여부에 따라 프롬프트를 동적으로 변경합니다. 확인하기 위해 다음 git 명령을 사용하고 있습니다.

if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
...

이제 현재 디렉토리가 무시되는지 여부도 구별하고 싶습니다 git. 그래서 선언문 if에 확인 사항을 하나 더 추가했습니다 .

if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1) && ! $(git check-ignore . >/dev/null 2>&1); then
...

이것은 잘 작동하지만 단일 명령으로 단순화할 수 있는지 궁금합니다 git. 프롬프트는 매번 새로 고쳐지기 때문에 ENTER일부 느린 시스템에서는 셸 속도가 크게 느려지는 경향이 있습니다.

고쳐 쓰다

@Stephen Kitt가 허용한 솔루션은 다음을 제외하고는 잘 작동합니다.

파일 시스템 전반에 걸쳐 저장소를 사용하고 있습니다. git이 다른 파티션/파일 시스템 에 있지만 /.git(구성 파일을 추적하고 싶기 때문에 /etc) git에 있는 일부 파일도 추적하고 싶다고 가정해 보겠습니다 ./var/foo

다음 명령을 실행 하면 /모든 것이 예상대로 작동하고 반환 코드를 얻습니다 1( /var/foo추적 중이므로).

# git check-ignore -q /var/foo

하지만 에 있으면 /var동일한 명령이 오류 코드 128와 다음 오류 메시지와 함께 실패합니다.

# git check-ignore -q /var/foo
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

하지만 내 생각엔 그것은 단지 check-ignore순서의 문제일 뿐이다. 그렇지 않으면 git이 파일 시스템에서 제대로 작동하는 것 같습니다. /var/foo파일을 잘 추적 할 수 있습니다 .

예상되는 동작은 추적되지 않는 경우 git check-ignore -q /var/foo반환 되는 것입니다 .1git check-ignore -q /var/bar0

이 문제를 어떻게 해결할 수 있나요?

답변1

git check-ignore ..저장소에 없으면 종료 코드 128로 실패하고(또는 다른 오류가 발생하면) git경로가 무시되지 않는 경우에만 종료 코드 1로 실패합니다. 따라서 후자만 확인할 수 있습니다.

git check-ignore -q . 2>/dev/null; if [ "$?" -ne "1" ]; then ... 

then내부적으로 git 저장소에서 무시되거나 무시되지 않는 상황을 처리하고 있습니다 ..

파일 시스템 경계를 넘어 작동하게 하려면 다음을 설정하십시오.GIT_DISCOVERY_ACROSS_FILESYSTEM도착하다 true:

GIT_DISCOVERY_ACROSS_FILESYSTEM=true git check-ignore -q . 2>/dev/null; if [ "$?" -ne "1" ]; then ...

답변2

가장 먼저 해야 할 일은:

if
  git rev-parse --is-inside-work-tree >/dev/null 2>&1 &&
    ! git check-ignore . >/dev/null 2>&1
then...

명령 대체( $(...))는 명령의 출력을 검색합니다. 여기서는 로 리디렉션할 때 출력이 없습니다 /dev/null. 출력이 있는 경우 실행될 명령으로 처리됩니다(종료 상태 확인).

두 번째 명령은 첫 번째 명령이 성공한 경우에만 실행됩니다.

git@StephenKitt는 이 두 명령을 하나의 명령 으로 나누는 방법을 보여주었습니다.하지만 그래도 성능에 도움이 되지 않는다면 언제든지 연관 배열에 정보를 캐시할 수 있습니다.

typeset -A is_git # declared globally in your ~/.zshrc
if (( ! $+is_git[$PWD] )); then
  git check-ignore -q . 2> /dev/null
  is_git[$PWD]=$(( $? == 1 ))
fi

if (( $is_git[$PWD] )); then...

디렉터리 이름을 바꾸거나, 디렉터리를 삭제 하거나, 무시된 파일 목록을 변경하면 .git이 캐시가 오래될 수 있습니다 . 이를 사용하거나 is_git=()재부팅 하여 비활성화할 수 있습니다 .zshexec zsh

또 다른 옵션은 후크를 사용하여 디렉토리가 입력될 때만 확인하는 것입니다 chpwd.

check_git() {
  git check-ignore -q . 2> /dev/null
  (( is_git = $? == 1 ))
}
chpwd_functions+=(check_git)

그런 다음 프롬프트 루틴에서 다음을 수행하십시오.

if (( is_git )); then...

관련 정보