Makefile에서 커밋되지 않은 변경 사항 (작업 트리 또는 인덱스)이있는 경우 특정 작업을 수행하고 싶습니다. 가장 깨끗하고 효율적인 방법은 무엇입니까? 어떤 경우에는 반환 값 0으로 종료하고 다른 경우에는 0이 아닌 명령이 내 목적에 적합합니다.
git status
출력을 통해 실행 하고 파이프 할 수는 grep
있지만 더 나은 방법이 있어야한다고 생각합니다.
Makefile에서 커밋되지 않은 변경 사항 (작업 트리 또는 인덱스)이있는 경우 특정 작업을 수행하고 싶습니다. 가장 깨끗하고 효율적인 방법은 무엇입니까? 어떤 경우에는 반환 값 0으로 종료하고 다른 경우에는 0이 아닌 명령이 내 목적에 적합합니다.
git status
출력을 통해 실행 하고 파이프 할 수는 grep
있지만 더 나은 방법이 있어야한다고 생각합니다.
답변:
UPDATE : 영업 다니엘 Stutzbach는 지적 코멘트에 이 간단한 명령이 있음을 git diff-index
그를 위해 일했다 :
git update-index --refresh
git diff-index --quiet HEAD --
( 노르 나곤 은 주석에 언급 되었지만, 만졌지만 색인과 내용이 동일한 파일이있는 경우 git update-index --refresh
이전 에 실행 해야 git diff-index
하며 그렇지 않으면 diff-index
트리가 더럽다고 잘못보고한다고 언급합니다)
bash 스크립트에서 명령 을 사용하는 경우 " 명령이 성공했는지 확인하는 방법? " 을 참조하십시오 .
git diff-index --quiet HEAD -- || echo "untracked"; // do something about it
참고 : 같이 주석 에 의해 안토니 Sottile
git diff-index HEAD ...
커밋이없는 분기 (예 : 새로 초기화 된 리포지토리)에서는 실패합니다.
내가 찾은 한 가지 해결 방법은git diff-index $(git write-tree) ...
그리고 haridsv
밖으로 점 코멘트에 그 git diff-files
A의 새로운 파일은 DIFF로 감지하지 않습니다.
보다 안전한 방법은 git add
파일 스펙에서 먼저 실행 한 다음 git diff-index
실행하기 전에 색인에 추가 된 항목이 있는지 확인하는 것 git commit
입니다.
git add ${file_args} && \ git diff-index --cached --quiet HEAD || git commit -m '${commit_msg}'
그리고 의견에 6502 보고서 :
내가 부딪친 한 가지 문제는
git diff-index
실제로 파일의 타임 스탬프를 제외하고는 실제로 차이가 없다는 것을 알 수 있다는 것입니다.
실행git diff
을 해결해 번 문제 (놀랍게도 것은,git diff
실제로 여기서 의미하는 샌드 박스의 내용을 변경 않습니다.git/index
)
이 타임 스탬프 문제는 git이 docker에서 실행되는 경우에도 발생할 수 있습니다 .
원래 답변 :
"프로그래밍 방식으로"는 절대로 도자기 명령에 의존하지 않습니다 .
항상 배관 명령 에 의존하십시오 .
또한 "을 참조하십시오 망할 놈의 더러운 지수 또는 비 추적 파일을 확인 (같은 대안" git status --porcelain
)
우리가 말한대로 작성된 새로운 " require_clean_work_tree
기능 " 에서 영감 을 얻을 수 있습니다 .) (2010 년 10 월 초)
require_clean_work_tree () {
# Update the index
git update-index -q --ignore-submodules --refresh
err=0
# Disallow unstaged changes in the working tree
if ! git diff-files --quiet --ignore-submodules --
then
echo >&2 "cannot $1: you have unstaged changes."
git diff-files --name-status -r --ignore-submodules -- >&2
err=1
fi
# Disallow uncommitted changes in the index
if ! git diff-index --cached --quiet HEAD --ignore-submodules --
then
echo >&2 "cannot $1: your index contains uncommitted changes."
git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2
err=1
fi
if [ $err = 1 ]
then
echo >&2 "Please commit or stash them."
exit 1
fi
}
git diff-index --quiet HEAD
했습니다..
HEAD
작업 디렉토리에 파일이 있으면 실패 할 수 있습니다 . 더 나은 사용 git diff-index --quiet HEAD --
.
git status --help
다음과 같습니다. --porcelain 구문 분석하기 쉬운 스크립트 출력을 제공합니다. 이것은 짧은 출력과 비슷하지만 사용자 구성에 관계없이 Git 버전에서 안정적으로 유지됩니다. 자세한 내용은 아래를 참조하십시오.
다른 솔루션은 매우 철저하지만 실제로 빠르고 더러운 것을 원하면 다음과 같이 해보십시오.
[[ -z $(git status -s) ]]
상태 요약에 출력이 있는지 확인합니다.
[[ ... ]]
실제로 구문이 무엇인지 알 수 있습니까? 나는 전에 그런 것을 본 적이 없다.
git status
는 실제로이 테스트에서 무시됩니다. 출력 만 봅니다. 확인 이 bash는 관련 페이지를 더에 대한 정보를 원하시면 [
, [[
bash는 작품을 테스트하는 방법에 대해 설명합니다.
git status -s -uall
추적되지 않은 파일을 포함하는 데 사용할 수 있습니다 .
git diff --exit-code
변경 사항이 있으면 0이 아닌 값을 반환합니다. git diff --quiet
출력이없는 것과 같습니다. 작업 트리와 색인을 확인하려면 다음을 사용하십시오.
git diff --quiet && git diff --cached --quiet
또는
git diff --quiet HEAD
커밋되지 않은 변경 사항이 준비되어 있는지 여부를 알려줍니다.
git diff --quite HEAD
은 인덱스가 깨끗한 지 여부가 아니라 작업 트리가 깨끗한 지 여부 만 알려줍니다. 예를 들어 file
HEAD ~와 HEAD 사이에서 변경된 경우 , 이후에도 git reset HEAD~ -- file
인덱스에 단계적 변경 사항 (wt == HEAD이지만 인덱스! = HEAD)이 있어도 0을 종료합니다.
git diff --quiet && git diff --cached --quiet
.
@Nepthar의 답변을 확장 :
if [[ -z $(git status -s) ]]
then
echo "tree is clean"
else
echo "tree is dirty, please commit changes before running this"
exit
fi
$(git status -s "$file")
에 다음과 else
절git add "$file"; git commit -m "your autocommit process" "$file"
git status -s
는 git status --porcelain ; git clean -nd
대신, 정크 디렉토리가 너무 여기 표면화 될 것이다 보이지있는 git status
.
다른 답변에서 지적했듯이 그러한 명령으로 간단합니다.
git diff-index --quiet HEAD --
마지막 두 개의 대시를 생략하면 파일 이름이이면 명령이 실패합니다 HEAD
.
예:
#!/bin/bash
set -e
echo -n "Checking if there are uncommited changes... "
trap 'echo -e "\033[0;31mFAILED\033[0m"' ERR
git diff-index --quiet HEAD --
trap - ERR
echo -e "\033[0;32mAll set!\033[0m"
# continue as planned...
주의 사항 :이 명령은 추적되지 않은 파일을 무시합니다.
git add
그리고 git clean
구조
준비되지 않은 파일과 준비된 파일을 나열하는 편리한 git 별칭을 만들었습니다.
git config --global alias.unstaged 'diff --name-only'
git config --global alias.staged 'diff --name-only --cached'
그러면 다음과 같은 작업을 쉽게 수행 할 수 있습니다.
[[ -n "$(git unstaged)" ]] && echo unstaged files || echo NO unstaged files
[[ -n "$(git staged)" ]] && echo staged files || echo NO staged files
PATH
호출 된 곳에 어딘가에 스크립트를 작성하여 더 읽기 쉽게 만들 수 있습니다 git-has
.
#!/bin/bash
[[ $(git "$@" | wc -c) -ne 0 ]]
이제 위의 예를 다음과 같이 단순화 할 수 있습니다.
git has unstaged && echo unstaged files || echo NO unstaged files
git has staged && echo staged files || echo NO staged files
완전성을 위해 추적되지 않은 파일과 무시 된 파일의 비슷한 별칭이 있습니다.
git config --global alias.untracked 'ls-files --exclude-standard --others'
git config --global alias.ignored 'ls-files --exclude-standard --others --ignored'
여기에 가장 깨끗하고 깨끗한 방법이 있습니다.
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
}
git status
'porcelain'명령입니다. git 버전간에 변경 될 수 있으므로 스크립트에서 도자기 명령을 사용하지 마십시오. 대신 '배관'명령을 사용하십시오.
git status --porcelain
(이 목적을 위해-스크립트에서 파싱 할 수있는 안정적인 형식을 의미합니다), 아마도 -z (줄 바꿈 대신 null로 구분되어 있습니까?)를 사용 하여이 아이디어로 유용한 것을 할 수 있다고 생각합니다 . @ codyc4321 자세한 내용은 stackoverflow.com/questions/6976473/… 을 참조하십시오