gitプリコミットスクリプト

gitプリコミットスクリプト

目的は、package-lock.json関連する変更がコミットされず、コミット時にゼロ以外の終了コードでスクリプトを終了することです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

関連情報