prosource

Git를 사용하여 더티 인덱스 또는 추적되지 않은 파일 확인

probook 2023. 5. 8. 22:18
반응형

Git를 사용하여 더티 인덱스 또는 추적되지 않은 파일 확인

Git 저장소에 커밋되지 않은 변경 사항이 있는지 확인하려면 어떻게 해야 합니까?

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

대본에서?

git-statusGit 버전 1.6.4.2에서는 항상 0을 반환하는 것 같습니다.

안정적으로 "스크립트 작성" Git의 핵심은 '플럼핑' 명령을 사용하는 것입니다.

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

안타깝게도 '매일' Git 명령은 '도자기' 명령이므로 대부분의 Git 사용자는 배관 명령에 익숙하지 않을 수 있습니다.자기 명령과 배관 명령은 메인 깃 맨 페이지에서 구분됩니다(고급 명령(도자기)낮은 수준 명령(배관) 하위 섹션 참조).


커밋되지 않은 변경사항에 대해 알아보려면 인덱스(및 작업 트리의 추적된 비트)를 다른 트리쉬(예:HEAD), (인덱스에 대해 작업 트리 표시), (목록 파일, 예를 들어 추적되지 않거나 무시되지 않은 파일을 나열합니다.

에서는 (으)로 표시됩니다.HEAD --는 대사다니됩용 됩니다.HEAD그렇지 않으면 이름이 지정된 파일이 있으면 명령이 실패하기 때문입니다.HEAD.)

리포지토리가 변경 사항을 준비했는지 여부(아직 커밋되지 않음)를 확인하려면 다음을 사용합니다.

git diff-index --quiet --cached HEAD --
  • 다음과 함께 종료되는 경우0.1차이가 있었다는 것을 의미합니다.

작업 트리에 스테이징할 수 있는 변경 내용이 있는지 확인하려면 다음과 같이 하십시오.

git diff-files --quiet
  • 종료 코드는 다음과 같습니다.git diff-index(0 없음; 차이없음;;1차이).

이 작트서인추덱파조적일다된합의관다음변확련니인지는합었경되업여하과리에이와스▁▁to▁the▁to▁in▁respect▁and다▁have▁whether▁changes▁check▁index니확인합▁the▁the▁of▁comb▁filesination작▁tree▁tracked업▁working▁the지와 관련하여 변경되었는지 확인합니다.HEAD:

git diff-index --quiet HEAD --
  • 이것은 앞의 두 가지를 합친 것과 같습니다.취소"한 "없음"을입니다.HEAD이와 같은 상황에서 두 개의 개별 명령은 모두 "차이 존재" 보고서를 반환합니다.

추적되지 않은 파일에 대해서도 언급하셨습니다."추적되지 않고 무시되지 않음"을 의미하거나 일반적인 "추적되지 않음"(무시 파일 포함)을 의미할 수 있습니다.쪽이든, 쪽이어든느,든▁either어쪽이.git ls-files입니다.

"추적되지 않음"(있는 경우 무시된 파일 포함)의 경우

git ls-files --others

"추적되지 않고 무시되지 않는" 경우:

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

첫 번째 생각은 다음 명령어가 출력되는지 확인하는 것입니다.

test -z "$(git ls-files --others)"
  • 다음과 함께 종료되는 경우0추적되지 않은 파일이 없습니다.다음과 함께 종료되는 경우1추적되지 않은 파일이 있습니다.

이것이 비정상적인 출구를 해석할 가능성은 거의 없습니다.git ls-files"추적되지 않은 파일 없음" 보고서로 변환합니다(둘 다 위 명령어가 0이 아닌 종료됨). 더 다음과 .

u="$(git ls-files --others)" && test -z "$u"
  • 이 아이디어는 이전 명령과 동일하지만 다음 명령에서 예상치 못한 오류가 발생할 수 있습니다.git ls-files는 "되지 않은 파일이 발생했음을 할 수 .이 경우 0이 아닌 종료는 "추적되지 않은 파일이 있음"을 의미하거나 오류가 발생했음을 의미할 수 있습니다.오류"와 "되지 않은 파일 하려면 "오류" "오류" "오류" "오류"를 합니다.test -n "$u"서 (의))0는 "일부 추적되지 않은 파일"을 의미하며, 0이 아닌 파일은 오류 또는 "추적되지 않은 파일 없음"을 의미합니다.

다른 아이디어는 사용하는 것입니다.--error-unmatch추적되지 않은 파일이 없을 때 0이 아닌 종료를 발생시킵니다.이는 또한 "추적되지 않은 파일 없음"을 혼동할 위험이 있습니다(종료).1) "오류가 발생했습니다"(0이 아닌 것으로 추정되지만 아마도128은.0대 대1종료 코드 대 0이 아닌 종료 코드는 상당히 강력할 수 있습니다.

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. 더티 상태의 경우:

    # 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)

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

편집:

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

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

향상된 Git 지원 셸 프롬프트

git 1.7.0 이상을 사용하고 있다고 가정하면...

이 페이지의 모든 답을 읽고 약간의 실험을 한 후, 정확성과 간결성의 올바른 조합에 도달하는 방법은 다음과 같습니다.

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

Git는 추적되는 것, 무시되는 것, 추적되지 않는 것, 무시되지 않는 것 등 사이에서 많은 미묘한 차이를 허용하지만, 일반적인 사용 사례는 체크아웃이 깨끗하지 않으면 모든 것을 중지하려는 빌드 스크립트 자동화에 사용됩니다.

합니다: type 이 경 프 우 로 시 이 일 션 타 하 것 합 니 당 다 는 이 레 뮬 을 는 하 가 그 머 래 니 ▁in 다 합 타 ▁what ▁type 당 것 , mer ▁it▁to ▁case ▁that ▁sensegit status출력을 확인합니다.하지만 우리는 특정 단어가 나타나는 것에 의존하고 싶지 않기 때문에, 우리는 그것을 사용합니다.--porcelain되지 않습니다.1.7.0은 출력되지 않습니다. 활성화하면 깨끗한 디렉토리가 출력되지 않습니다.

다음 는 그면우는을 사용합니다.test -n출력이 있는지 없는지 확인합니다.

이 명령은 작업 디렉터리가 깨끗하면 1을 반환하고 커밋할 변경 사항이 있으면 0을 반환합니다. 변경할 수 .-n-z당신이 반대를 원한다면요.이 기능은 스크립트의 명령에 연결하는 데 유용합니다.예:

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

이것은 효과적으로 "변경할 내용이 없거나 알람을 설정할 수 있습니다"라고 말합니다. 이 한 줄은 작성 중인 스크립트에 따라 if-statement보다 더 나을 수 있습니다.

VonC의 답변에서 구현:

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

몇 가지 답을 살펴봤는데,(*nix 및 window에서 다양한 문제가 발생했습니다. 이는 제가 요구하는 사항이었습니다.)다음이 잘 작동한다는 것을 알았습니다...

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

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

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

창 $에서 종료 코드를 확인하려면 다음과 같이 하십시오.

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

https://github.com/sindresorhus/pure/issues/115 에서 출처 제공 공유를 위한 게시물의 @paulirish 덕분입니다.

'슐화하지이유캡는않'를 요?git status다음과 같은 스크립트를 사용합니다.

  • 해당 명령의 출력을 분석합니다.
  • 필요한 항목에 따라 적절한 오류 코드를 반환합니다.

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


0xfe훌륭한 답변에서 언급했듯이, 스크립트 기반 솔루션에서 중요한 역할을 참조하십시오.

--porcelain

출력을 안정적이고 구문 분석하기 쉬운 스크립트 형식으로 제공합니다.
은 현재이다같습다니음과은것▁to다와 동일합니다.--short output그러나 이후에는 변경되지 않으므로 스크립트에 안전합니다.

0xfe의 제안에 따라 업데이트된 하나의 DIY 가능성

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

Chris Johnsen이 언급한 대로 Git 1.7.0 이상에서만 작동합니다.

또한 할 수 있습니다.

git describe --dirty

더러운 작업 트리를 감지하면 끝에 "-dirty"라는 단어가 추가됩니다.에 의하면git-describe(1):

   --dirty[=<mark>]
       Describe the working tree. It means describe HEAD and appends <mark> (-dirty by default) if
       the working tree is dirty.

주의: 추적되지 않은 파일은 "더티"로 간주되지 않습니다. 이는 manpage에 명시된 대로 작업 트리에만 관심이 있기 때문입니다.

실행이 끝나면 수정된 추적 파일이나 무시되지 않는 추적되지 않은 파일이 있을 경우 빌드를 실패하는 간단한 방법이 필요했습니다.

이는 빌드로 인해 잔여물이 생성되는 경우를 방지하는 데 매우 중요합니다.

지금까지 사용한 최고의 명령어는 다음과 같습니다.

 test -z "$(git status --porcelain | tee /dev/fd/2)" || \
     {{ echo "ERROR: git unclean at the end, failing build." && return 1 }}

조금 복잡해 보일 수 있으며 원하는 동작을 유지하는 단락 변형을 찾는 사람이 있다면 감사하겠습니다.

  • 출력 없음 및 종료 코드 성공(모든 항목이 정상인 경우)
  • 실패하면 코드 1을 종료합니다.
  • 실패 이유를 설명하는 stderr의 오류 메시지
  • 오류의 원인이 되는 파일 목록을 표시합니다. 다시 stderr.

@eduard-wirch 답변은 꽤 완벽했지만, 동시에 두 가지를 확인하고 싶었기 때문에, 여기 제 최종 변형이 있습니다.

        set -eu

        u="$(git ls-files --others)"
        if ! git diff-index --name-only --quiet HEAD -- || [ -z "${u:-}" ]; then
            dirty="-dirty"
        fi

set -e 또는 동등한 것을 사용하여 실행하지 않을 때, 우리는 대신 다음을 수행할 수 있습니다.u="$(git ls-files --others)" || exit 1 이것이 된 함수에 반환합니다 (또는사용기대작경우반환할동해능에된▁())반▁if)

따라서 untracked_files는 명령이 제대로 성공한 경우에만 설정됩니다.

그런 다음 두 가지 속성을 모두 확인하고 변수(또는 기타)를 설정할 수 있습니다.

이는 저장소에 추적되지 않은 파일이 있는지 확인하기 위한 셸 친화적인 변형입니다.

# Works in bash and zsh
if [[ "$(git status --porcelain 2>/dev/null)" = *\?\?* ]]; then
  echo untracked files
fi

이건 두 번째 과정을 방해하지 않습니다.grepGit 저장소에 있는지 확인할 필요가 없습니다.셸 프롬프트 등에 편리한 것.

이 스레드에서 더 나은 답변 조합이 있을 수 있습니다.하지만 이건 내게 효과가 있어요당신을 위하여.gitconfig[alias]섹션...

          # git untracked && echo "There are untracked files!"
untracked = ! git status --porcelain 2>/dev/null | grep -q "^??"
          # git unclean && echo "There are uncommited changes!"
  unclean = ! ! git diff --quiet --ignore-submodules HEAD > /dev/null 2>&1
          # git dirty && echo "There are uncommitted changes OR untracked files!"
    dirty = ! git untracked || git unclean

더티 상태 감지에 사용하는 가장 간단한 자동 테스트 = 추적되지 않은 파일을 포함한 모든 변경 사항:

git add --all
git diff-index --exit-code HEAD

비고:

  • 없이.add --all추적되지diff-index 않은 파일을 인식하지 못합니다.
  • 보통 나는 달립니다.git reset오류 코드를 테스트한 후 모든 것을 취소합니다.
  • 고하다려를 생각해 .--quiet--exit-code출력을 방지하기 위해.

여기에 가장 좋고 깨끗한 방법이 있습니다.선택한 응답이 어떤 이유에서인지 작동하지 않았습니다. 커밋되지 않은 새 파일인 스테이징된 변경 사항을 확인하지 못했습니다.

function git_dirty {
    text=$(git status)
    changed_text="Changes to be committed"
    untracked_files="Untracked files"

    dirty=false

    if [[ ${text} = *"$changed_text"* ]];then
        dirty=true
    fi

    if [[ ${text} = *"$untracked_files"* ]];then
        dirty=true
    fi

    echo $dirty
}

언급URL : https://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git

반응형