목표는 package-lock.json
관련된 변경 사항이 커밋되지 않고 커밋 시 0이 아닌 종료 코드로 스크립트를 종료하는 것입니다 package.json
.
#!/bin/bash
# exits with 1 if there were differences and 0 means no differences
file_changed() {
git diff --quiet --exit-code "$1"
}
# exits with 1 if no lines were selected, 0 if one or more lines selected, > 1 if error
file_staged() {
git diff --name-only --cached | grep -q "$1"
}
# package-lock.json has changed and
# package-lock.json in staged files and
# package.json not in staged files?
if [[ file_changed "package-lock.json" -eq 1 &&
file_staged "package-lock.json" -eq 0 &&
file_staged "package.json" -eq 1 ]]
then
echo "attempted commit of package-lock.json without changes to package.json!"
exit 1
fi
문제가 내 기능에 있다고 확신합니다 files_staged
. 테스트를 해보니 file_staged "package-lock.json" -eq 0
예상했던 결과를 얻었습니다. 테스트할 때 항상 실패합니다 file_staged "package.json" -eq 1
.
package.json
문제를 단순화하면 반환된 파일 목록에 없을 때 이 조건을 트리거할 수 없습니다 git diff --name-only --cached
.
if file_staged "package.json" -eq 1; then
echo "got here."
fi
내가 어디서 잘못됐나요?
편집하다
$()
@Jesse_b는 숫자 비교 연산자가 함수에 대한 인수로 전송되지 않도록 함수 호출 주위에서 사용해야 한다고 지적했습니다 . 다음 예에서는 여전히 원하는 결과를 제공하지 않습니다.
if [[ $(file_staged "package.json") -eq 1 ]]; then
echo "got here."
fi
답변1
if
구성의 어떤 조건도 작동하지 않습니다. 테스트 명령( test
, [
, ) 을 사용하지 않으므로 [[
함수의 반환 상태만 테스트하고 있습니다.
예:
$ test () { echo 0; }
$ if test -eq 1; then echo yes; fi
0
yes
$ if test -eq 10; then echo yes; fi
0
yes
$ if test -eq 100000000000; then echo yes; fi
0
yes
-eq ...
함수 에 대한 옵션으로 간주 되며 test
함수는 0을 반환하므로 성공한 것으로 간주됩니다.
테스트 명령을 사용하고 싶습니다.
if [[ $(file_changed "package-lock.json") -eq 1 &&
$(file_staged "package-lock.json") -eq 0 &&
$(file_staged "package.json") -eq 1 ]]
then
echo "attempted commit of package-lock.json without changes to package.json!"
exit 1
fi