Git 작업 디렉토리가 스크립트에서 깨끗한 지 확인 있습니다. 작업 디렉토리가 깨끗한

rsyncGit 작업 디렉토리를 대상으로 실행하는 스크립트가 있습니다. 작업 디렉토리가 깨끗한 지 (커밋을 변경하지 않았는지) 여부에 따라 스크립트가 다른 동작을 갖기를 원합니다. 예를 들어의 출력이 git status아래와 같으면 스크립트를 종료하고 싶습니다.

git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date

디렉토리가 깨끗하지 않으면 더 많은 명령을 실행하고 싶습니다.

쉘 스크립트에서 위와 같은 출력을 어떻게 확인할 수 있습니까?



답변

git status출력은 기계가 아니라 사람이 읽을 수 있도록 만들어 졌으므로 출력을 구문 분석 하는 것은 좋지 않습니다. 향후 버전의 Git 또는 다르게 구성된 환경에서 출력이 동일하게 유지된다는 보장은 없습니다.

UVV 주석은 올바른 방향에 있지만 불행하게도 git status커밋되지 않은 변경 사항이있을 때 반환 코드는 변경되지 않습니다. 그것은, 그러나, 제공합니까 --porcelain의 출력됩니다 옵션, git status --porcelain스크립트 쉬운 구문 분석 형식으로 포맷하기를, 그리고 힘내 버전에서 안정적으로 유지와 관계없이 사용자 구성됩니다.

git status --porcelain커밋 할 변경 사항이 없음을 표시로 빈 출력을 사용할 수 있습니다 .

if [ -z "$(git status --porcelain)" ]; then
  # Working directory clean
else
  # Uncommitted changes
fi

작업 디렉토리에서 추적되지 않은 파일에 신경 쓰지 않으면 --untracked-files=no옵션을 사용하여 파일 을 무시할 수 있습니다 .

if [ -z "$(git status --untracked-files=no --porcelain)" ]; then
  # Working directory clean excluding untracked files
else
  # Uncommitted changes in tracked files
fi

조건에 대해이 더 강력한 만들려면 실제로 원인 git status을 출력하지 않고 실패 stdout, 우리는 수표를 구체화 할 수 있습니다 :

if output=$(git status --porcelain) && [ -z "$output" ]; then
  # Working directory clean
else
  # Uncommitted changes
fi

그것은 있지만, 또한 주목할 것을 가치가 git status작업 디렉토리가 부정 일 때 의미가 종료 코드를 제공하지 않습니다, git diff제공 --exit-code가 유사 행동하게 옵션 은 diff 유틸리티를, 그 상태에 빠져있다 1가 차이가 있었다 때 0아무 것도 찾을 수 없습니다 때.

이를 사용하여 다음과 같이 비 단계적 변경을 확인할 수 있습니다.

git diff --exit-code

다음과 같은 단계적이지만 커밋되지 않은 변경 사항이 있습니다.

git diff --cached --exit-code

git diff에 대한 적절한 인수를 통해 서브 모듈에서 추적되지 않은 파일을보고 할 수 있지만 --ignore-submodules불행히도 실제 작업 디렉토리에서 추적되지 않은 파일에 대해보고 할 방법이없는 것 같습니다. 작업 디렉토리의 추적되지 않은 파일이 관련이 있다면 git status --porcelain아마도 가장 좋은 방법 일 것입니다.


답변

사용하다:

git diff-index --quiet HEAD

리턴 코드는 작업 디렉토리의 상태를 반영합니다 (0 = 정리, 1 = 더티). 추적되지 않은 파일은 무시됩니다.


답변

André의 탁월한 답변에 대한 사소한 확장 .

이것은 결과를 평가하고 이전에 set -e를 실행 한 스크립트에있는 경우 함정을 피하는 한 가지 방법 입니다.

추적되지 않은 파일은 무시됩니다.

set +e
git diff-index --quiet HEAD

if [ $? == 1 ] ; then
  set -e
  GIT_MODS="dirty"
else
  set -e
  GIT_MODS="clean"
fi


답변