git 사전 커밋 스크립트

git 사전 커밋 스크립트

목표는 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

관련 정보