태그 보관물: shell

shell

Git으로 더티 인덱스 또는 추적되지 않은 파일 확인 내 git 저장소에

내 git 저장소에 커밋되지 않은 변경 사항이 있는지 어떻게 확인할 수 있습니까?

  1. 인덱스에 추가되었지만 커밋되지 않은 변경 사항
  2. 추적되지 않은 파일

스크립트에서?

git-status git 버전 1.6.4.2에서는 항상 0을 반환하는 것으로 보입니다.



답변

좋은 타이밍! 나는 며칠 전에 정확하게 git status 정보를 프롬프트에 추가하는 방법을 알았을 때 블로그 게시물을 작성했습니다.

내가하는 일은 다음과 같습니다.

  1. 더티 상태의 경우 :

    # Returns "*" if the current git branch is dirty.
    function evil_git_dirty {
      [[ $(git diff --shortstat 2> /dev/null | tail -n1) != "" ]] && echo "*"
    }
  2. 추적되지 않은 파일의 경우 ( 파싱 ​​가능한 출력을 제공 하는 --porcelain플래그에 유의하십시오 git status) :

    # Returns the number of untracked files
    
    function evil_git_num_untracked_files {
      expr `git status --porcelain 2>/dev/null| grep "^??" | wc -l`
    }

git diff --shortstat더 편리 하지만 git status --porcelain더티 파일을 얻는 데 사용할 수도 있습니다 .

# Get number of files added to the index (but uncommitted)
expr $(git status --porcelain 2>/dev/null| grep "^M" | wc -l)

# Get number of files that are uncommitted and not added
expr $(git status --porcelain 2>/dev/null| grep "^ M" | wc -l)

# Get number of total uncommited files
expr $(git status --porcelain 2>/dev/null| egrep "^(M| M)" | wc -l)

참고 : 2>/dev/null오류 메시지를 필터링하여 비 git 디렉토리에서 이러한 명령을 사용할 수 있습니다. (그들은 단순히 돌아올 것이다.0 파일 수 합니다.)

편집하다 :

게시물은 다음과 같습니다.

터미널 프롬프트에 Git 상태 정보 추가

향상된 Git 지원 쉘 프롬프트


답변

Git을“스크립트”로 확실하게 만드는 열쇠는 ‘배관’명령을 사용하는 것입니다.

개발자는 배관 명령을 변경할 때 매우 안정적인 인터페이스를 제공하도록주의를 기울입니다 (예 : 지정된 저장소 상태, stdin, 명령 행 옵션, 인수 등의 조합이 명령 / 명령이있는 모든 버전의 Git에서 동일한 출력을 생성 함) 옵션이 존재합니다). 배관 명령의 새로운 출력 변형은 새로운 옵션을 통해 도입 될 수 있지만 이전 버전에 대해 이미 작성된 프로그램에는 아무런 문제가 발생할 수 없습니다 (새로운 옵션은 존재하지 않았기 때문에 (또는 적어도 사용되지 않음) 스크립트가 작성된 시점).

불행히도 ‘매일’Git 명령은 ‘porcelain’명령이므로 대부분의 Git 사용자는 배관 명령에 익숙하지 않을 수 있습니다. 자기 명령과 배관 명령의 구분은 기본 git 맨 페이지 에서 이루어집니다 (하위 레벨 명령 (도자기)하위 레벨 명령 (배관) 이라는 하위 섹션 참조 ) .


커밋되지 않은 변경 사항을 찾으려면 git diff-index다른 트리 (예 :)와 비교하여 인덱스 (및 작업 트리의 추적 비트 비교 HEAD), git diff-files(인덱스와 작업 트리 비교) 및 git ls-files(파일 목록; 추적되지 않은 목록 나열) , 무시되지 않은 파일).

(아래 명령에서 이라는 파일 있으면 명령 이 실패 하기 때문에 HEAD --대신 사용됩니다 .)HEADHEAD

리포지토리가 단계적 변경 (아직 커밋되지 않은)을 확인하려면 다음을 사용하십시오.

git diff-index --quiet --cached HEAD --
  • 종료되면 0차이가 없었습니다 (차이가 1있음을 의미).

작업 트리에 스테이징 가능한 변경 사항이 있는지 확인하려면 다음을 수행하십시오.

git diff-files --quiet
  • 종료 코드는 git diff-index( 0== 차이점 없음; 1== 차이점)과 동일합니다.

작업 트리에서 색인과 추적 된 파일의 조합이 다음과 관련하여 변경되었는지 확인하려면 다음을 수행하십시오 HEAD.

git diff-index --quiet HEAD --
  • 이것은 이전 두 가지의 조합과 같습니다. 주요한 차이점 중 하나는 작업 트리에서 “실행 취소”한 단계적 변경 사항이있는 경우 여전히 “차이 없음”을보고한다는 것입니다 (에있는 내용으로 돌아 가기 HEAD). 이와 같은 상황에서 두 개의 개별 명령은 모두 “차이가 존재”한다는 보고서를 반환합니다.

추적되지 않은 파일도 언급했습니다. “추적되지 않은 및 무시 됨”을 의미하거나 일반 “추적되지 않은”(무시 된 파일 포함)을 의미 할 수 있습니다. 어느 쪽이든 git ls-files, 작업을위한 도구입니다.

“추적되지 않은”의 경우 (있는 경우 무시 된 파일 포함) :

git ls-files --others

“추적되지 않은 및 무시 된”의 경우 :

git ls-files --exclude-standard --others

내 첫 번째 생각은 이러한 명령에 출력이 있는지 확인하는 것입니다.

test -z "$(git ls-files --others)"
  • 종료되면 0추적되지 않은 파일이 없습니다. 종료되면 1추적되지 않은 파일이 있습니다.

이로 인해 비정상 종료가 git ls-files“추적되지 않은 파일 없음”보고서로 변환 될 가능성이 적습니다 (두 가지 모두 위 명령이 종료되지 않음). 좀 더 강력한 버전은 다음과 같습니다.

u="$(git ls-files --others)" && test -z "$u"
  • 아이디어는 이전 명령과 동일하지만 예기치 않은 오류 git ls-files가 전파 될 수 있습니다. 이 경우, 0이 아닌 종료는 “추적되지 않은 파일이 있음”을 의미하거나 오류가 발생했음을 의미 할 수 있습니다. 대신 “오류”결과와 “추적되지 않은 파일 없음”결과를 함께 사용하려면 test -n "$u"종료를 0“추적되지 않은 일부 파일”, 0이 아닌 경우 오류 또는 “추적되지 않은 파일 없음”을 사용하십시오.

또 다른 아이디어는 --error-unmatch추적되지 않은 파일이 없을 때 0이 아닌 종료를 발생시키는 데 사용 하는 것입니다. 또한 1“오류가 발생했습니다”(0이 아닌 경우도 있지만)로 ” 추적되지 않은 파일 없음”(종료 ) 을 병합 할 위험이 있습니다 128. 그러나 0이 아닌 종료 코드 01vs. 종료 코드를 확인하는 것은 상당히 강력합니다.

git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$?
if test "$ec" = 0; then
    echo some untracked files
elif test "$ec" = 1; then
    echo no untracked files
else
    echo error from ls-files
fi

추적되지 않은 파일과 무시되지 않은 파일 만 고려하려는 경우 위의 git ls-files예를 사용할 수 있습니다 --exclude-standard.


답변

git 1.7.0 이상이라고 가정하면 …

이 페이지의 모든 답변과 몇 가지 실험을 읽은 후 정확성과 간결함의 올바른 조합을 달성하는 방법은 다음과 같습니다.

test -n "$(git status --porcelain)"

git은 추적, 무시, 추적되지 않지만 무시되지 않은 것들 사이에 많은 뉘앙스를 허용하지만, 일반적인 사용 사례는 빌드 스크립트를 자동화하는 것이며, 체크 아웃이 깨끗하지 않으면 모든 것을 중지하려는 경우입니다.

이 경우 프로그래머가하는 일을 시뮬레이션하는 것이 합리적입니다 : git status출력을보고 입력 하십시오. 그러나 특정 단어가 표시되는 것을 원하지 않기 때문에 --porcelain1.7.0에 도입 된 모드를 사용합니다 . 사용 가능한 경우, 클린 디렉토리는 출력되지 않습니다.

그런 다음 test -n출력이 있는지 여부를 확인 하는 데 사용 합니다.

이 명령은 작업 디렉토리가 깨끗하면 1을 반환하고 커밋해야 할 변경 사항이 있으면 0을 반환합니다. 당신은을 변경할 수 있습니다 -nA와 -z는 반대합니다. 스크립트의 명령에이를 연결하는 데 유용합니다. 예를 들면 다음과 같습니다.

test -z "$(git status --porcelain)" || red-alert "UNCLEAN UNCLEAN"

이것은 “변경하거나 알람을 설정하지 않습니다”라고 효과적으로 말합니다. 이 one-liner는 작성하는 스크립트에 따라 if 문보다 선호 될 수 있습니다.


답변

VonC 의 답변 에서 구현 :

if [[ -n $(git status --porcelain) ]]; then echo "repo is dirty"; fi

답변

이 답변 중 몇 가지를 살펴 보았습니다 … (그리고 * nix와 windows에 대한 다양한 문제가 있었지만 요구 사항이었습니다) … 다음이 잘 작동한다는 것을 알았습니다 …

git diff --no-ext-diff --quiet --exit-code

* nix에서 종료 코드를 확인하려면

echo $?
#returns 1 if the repo has changes (0 if clean)

window $에서 종료 코드를 확인하려면

echo %errorlevel%
#returns 1 if the repos has changes (0 if clean) 

https://github.com/sindresorhus/pure/issues/115 에서 제공
합니다. 공유를 위해 해당 게시물에 @paulirish에게 감사드립니다.


답변

다음 git status과 같은 스크립트로 ‘ 를 캡슐화하지 마십시오 .

  • 해당 명령의 출력을 분석합니다
  • 필요한 것을 기반으로 적절한 오류 코드를 반환합니다

이렇게하면 스크립트에서 해당 ‘향상된’상태를 사용할 수 있습니다.


으로 0xFE로는 그의에서 언급 우수한 대답 , git status --porcelain모든 스크립트 기반 솔루션에서 쓸모있다

--porcelain

스크립트를 위해 안정적이고 분석하기 쉬운 형식으로 출력을 제공하십시오.
현재 이것은와 동일 --short output하지만 향후 변경되지 않으므로 스크립트에 안전합니다.


답변

하나의 DIY 가능성, 0xfe 의 제안 을 따르도록 업데이트 됨

#!/bin/sh
exit $(git status --porcelain | wc -l) 

Chris Johnsen 이 언급했듯이 이것은 Git 1.7.0 이상에서만 작동합니다.