前言
如题,真是小小又丑丑🤡 👈🤣,跟自己爆了。
也不是第一次出现这样的事了,图快没看提示,部署完了才发现有问题。
不能忍了,刚好最近有空闲时间,简单研究一下解决方案,先贴出最后的样子:
思路
联想
作为程序员,很自然就想到,在提交前检查一下是否有文件没有进行 git add,这个功能又很自然联想到 husky + commitlint 两件套。
有的同学可能没有接触过这个,大概就是在提交的时候检查你的 commit 信息符不符合固定格式,如 feat: xxxxx 能通过,但直接 xxxxx 不行
git husky & commitlint
既然如此,我们来稍微了解一下 git husky。
git 在提交代码时,会有一个完整的生命周期,并暴露出一些钩子,如
pre-commit :在 git commit
执行前(输入提交消息之前)
prepare-commit-msg :在 pre-commit
之后,默认提交消息准备好之后(但允许修改)。
commit-msg:在用户输入提交消息后,提交完成前。
post-commit:提交完成后。
...
还有许多钩子如 merge 时、rebase 时,这里不一一赘述。只需要知道它暴露出来很多个钩子即可(有点类似 vue 的 mounted、created 这堆东西)
我们所熟知的 commitlint 就是运行在 commit-msg 这个环节,来检查他的 commit 信息对不对。
切入
所以我们也需要找到所需的钩子,一眼 pre-commit ,我们在这里写我们的检测脚本即可。
有的同学可能会说,imooimoo我不会写 sh 怎么办啊,学习成本太高了呀。
别担心,我也不会写,直接上 ai
bash
# .husky/pre-commit 文件
# 检查是否有未 add 的文件
if [ -n "$(git diff --name-only)" ]; then
echo "❌ 警告: 当前项目未完全 add,存在未暂存的修改。" >/dev/tty
exit 1
fi
我觉得这才是 ai 的正确使用方式。准确描述出问题提供给 ai,并且能简单看懂它产出的代码,就没什么问题。
优化
做都做了,不妨做的更漂亮一些。
刚才的代码时直接中断,现在让它识别指令,这样可以允许它自己 add . ,并且继续 commit,就不用我们再手动 add 后并且重新 commit 了。
bash
# 检查是否有未 add 的文件
if [ -n "$(git diff --name-only)" ]; then
echo "❌ 警告: 当前项目未完全 add,存在未暂存的修改。" >/dev/tty
printf "是否继续?按 y 继续,按 a 全部 add 并继续,按其他键取消: " >/dev/tty
# 从终端设备直接读取输入,而不是从标准输入
read -n 1 REPLY </dev/tty
echo >/dev/tty
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "继续提交..." >/dev/tty
elif [[ $REPLY =~ ^[Aa]$ ]]; then
echo "执行 git add . 添加所有文件..." >/dev/tty
git add .
echo "✅ 已成功添加所有文件,继续提交..." >/dev/tty
else
echo "❌ 提交已取消" >/dev/tty
exit 1
fi
fi
更进一步
还是那句话,来都来了,那就把 eslint 和 tsc 扫描都加上吧,反正是ai 写
bash
#!/usr/bin/env sh
. "$(dirname -- " $0")/_/husky.sh"
# 检查是否有需要提交的文件(已暂存的文件)
if [ -z "$(git diff --staged --name-only)" ]; then
echo "❌ 错误: 没有暂存的文件,无法提交。" >/dev/tty
exit 1
fi
# 检查是否有未 add 的文件
if [ -n "$(git diff --name-only)" ]; then
echo "❌ 警告: 当前项目未完全 add,存在未暂存的修改。" >/dev/tty
printf "是否继续?按 y 继续,按 a 全部 add 并继续,按其他键取消: " >/dev/tty
read -n 1 REPLY </dev/tty
echo >/dev/tty
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "继续提交..." >/dev/tty
elif [[ $REPLY =~ ^[Aa]$ ]]; then
echo "执行 git add . 添加所有文件..." >/dev/tty
git add .
echo "✅ 已成功添加所有文件,继续提交..." >/dev/tty
else
echo "❌ 提交已取消" >/dev/tty
exit 1
fi
fi
# 获取暂存区的文件列表
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '.(js|jsx|ts|tsx)$')
# 执行 ESLint 扫描,只检查暂存区的文件
echo "正在执行 ESLint 检查暂存区文件..." >/dev/tty
echo "$STAGED_FILES" | xargs npx eslint
# 检查 ESLint 是否通过
if [ $? -ne 0 ]; then
echo "❌ESLint 检查未通过,请修复上述问题后再提交" >/dev/tty
exit 1
else
echo "✅ESLint 检查通过!\n" >/dev/tty
fi
# 添加 TypeScript 类型检查,只检查暂存区的文件
echo "执行全局 TypeScript 类型检查..." >/dev/tty
npx tsc -b
就这样,又学到一招,散会!