目标是在提交时以非零退出代码退出脚本,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