如何在预提交挂钩中使用 git diff 的退出代码
Posted
技术标签:
【中文标题】如何在预提交挂钩中使用 git diff 的退出代码【英文标题】:How to use exit code of git diff in pre-commit hook 【发布时间】:2021-12-05 11:15:38 【问题描述】:我有一个带有后端和前端的项目,但是由于每次更改都会执行 git pre-commit 挂钩,因此我需要检查更改是否在前端进行。
我尝试了这个预提交挂钩:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
git diff --cached --name-only --quiet frontend
if [ $? -eq 1 ]; then
cd frontend && npm run lint
fi
但由于某种原因,它在运行 git 命令时失败了——这在我的终端中运行良好。我得到的错误是:
husky - pre-commit 钩子以代码 1 退出(错误)
这并没有真正的帮助。我的猜测是 git 命令返回一个错误代码,脚本就这样结束了。
知道如何解决这个问题吗?
【问题讨论】:
git diff
将在有更改时返回 1。 [
也将有一个退出代码(它需要,否则 if
无法检查退出代码)。你总是想用代码 0 退出你的脚本吗?如果是这样,true
作为最后一个命令可能会有所帮助。
@knittl 感谢您的回答,但您能提示一下您的意思吗?我对shell脚本一无所知。我要做的就是运行 git diff 并检查其返回值是否为 1。如果是,请运行 lint 命令。但是如何防止 git 将其返回到 shell 并保存以进行比较?
如果您需要脚本始终成功退出,true
作为最后一个命令可能会这样做。 (我已经在我的第一条评论中写过这个;))。说明:true
总是成功退出。 shell 脚本退出时使用与最后执行的命令相同的代码(或使用exit
指定的代码)。所以实际上,exit 0
可能比true
更明确:)
我的问题是我不知道语法。我不知道在哪里把“真实”放在哪里。
【参考方案1】:
shell 脚本总是以最后执行的命令的退出代码或使用 exit
内置命令指定的代码退出。
如果您需要脚本始终以特定的退出代码退出(例如,始终成功,0
),请确保您明确指定退出代码:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
git diff --cached --name-only --quiet frontend
if [ $? -eq 1 ]; then
cd frontend && npm run lint
fi
exit 0
【讨论】:
但是我又想知道:这种预提交挂钩的目的是什么?如果 linting 失败,它仍然会成功退出,因此没有任何价值。还是npm run lint
实际格式化/更改文件?
谢谢。我真的很困惑,因为它看起来永远不会到达终点。我们在同一个存储库中有一个后端和前端,但提交挂钩属于存储库。如果后端开发没有在前端文件夹中安装 npm 依赖项,则它们的构建将失败。我想阻止这种情况。仅当前端文件夹发生更改时,linter 才必须运行。
@ctwx: 那么你想要脚本以npm run lint
的退出状态退出如果你正在运行npm run lint
。否则,您希望脚本以状态 0 退出。因此,明确的、始终到达的 exit 0
是错误的。我可能会把它写成if ! git diff-index --cached --quiet HEAD -- frontend; then cd frontend && npm run lint; fi
,这应该可以实现。以上是关于如何在预提交挂钩中使用 git diff 的退出代码的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 上的 Git Bash 中退出“git diff”的结果? [复制]