Skip to content

[git hooks] pre-commit 配置 #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
some-code opened this issue Jun 1, 2018 · 1 comment
Open

[git hooks] pre-commit 配置 #4

some-code opened this issue Jun 1, 2018 · 1 comment

Comments

@some-code
Copy link
Owner

some-code commented Jun 1, 2018

在开发过程中,通常使用 eslint 来规范团队的代码风格。但是 eslint 只能在开发服务器启动的时候才去检验代码。如果一个人在不启动开发服务器的情况下,修改了代码直接提交到git,那么别人pull下来的代码肯定会报错,我们需要把错误遏制在提交之前。

唯一的麻烦可能是地震的时候commit不太方便
------- 一位成都前端开发者留言说

git hooks 是什么

git hooks 是git的一种钩子机制,可以让用户在git操作的各个阶段执行自定义的逻辑。

git hooks 在项目根目录的 .git/hooks 下面配置,配置文件的名称是固定的,使用shell语法编写。

里面包含 pre-commit , pre-push , commit-msg等多种钩子,具体可以查看 Git 钩子

从头编写如此多的 shell脚本 太难,所以我们使用 husky 来帮我们自动生成这些 shell脚本

husky是什么

husky 就是一款用于处理 git hooks 的npm包包。

安装好 husky,他会自动在项目的 .git/hooks 文件夹下面生成各种配置文件。
如果你在git init之前已经安装了 husky,那么需要卸载掉再重装才能使用。

pre-commit 举例

不推荐使用 husky 来管理 pre-commit,因为他只是简单的运行 npm run lint命令来检测当前的文件状态,而无法检测仅仅暂存区的文件。推荐使用以下配置通过检测暂存区文件,来阻止不规范代码的提交。
这是 .git/hooks/pre-commit 文件的源码:

#!/bin/bash

# 如果在commit时有未添加到暂存区的文件,拒绝提交
diff=$(git diff)
if [[ $diff !=0 ]];then
  echo "some files is changed but not add to stash, git commit denied"
  exit 1
fi

# 读取git暂存区的.js 和 .vue文件
files=$(git diff --cached --name-only | grep -E '\.js$|\.vue$')

# 在控制台打印文件列表
echo $files
# Prevent ESLint help message if no files matched

# 如果文件列表为空,退出执行环境,继续执行commit操作
if [[ $files = "" ]] ; then
    exit 0
fi

failed=0

# 循环文件列表
for file in ${files}; do
    # 判断文件是否存在(-e 表示 exists)
    if [ ! -e $file ] ; then
        continue
    fi
    
    # 在控制台打印该文件的eslint检验结果,如果通过,则返回空
    git show :$file | ./node_modules/.bin/eslint $file --color --fix
    
    # 文件未通过eslint检验,标记为失败
    if [[ $? != 0 ]] ; then
        failed=1
    fi
done;

# 有文件未通过检验,退出执行环境,中断commit操作
if [[ $failed != 0 ]] ; then
    echo "❌  ESLint failed, git commit denied"
    exit $failed
fi

从文件源码可以看出,git 将会在你将文件添加到暂存区后,执行eslint操作,通不过操作的时候,这次操作将被取消 (shell exit 1)。

注意,需要使用npm而不是yarn安装node_modules

通过测试发现,如果通过 yarn add 的方式安装 eslint , babel-eslint 的话,这句代码将会报错:

git show :$file | ./node_modules/.bin/eslint $file --color --fix

只用用npm重新安装上面提到的一些包,才能在 ./node_modules/.bin 目录下找到eslint,不知道你们有没有遇到这样的问题。

注意,需要使用unix文件编码

git hooks 需要的 shell脚本,需要是unix文件格式才能正常运行。

否则windows10系统会抛出换行符错误,而macOS则会抛出 pre-commit 不是文件或者文件夹的错误。

需要打开bash,使用如下命令修改,方可正常使用。

vi ./.git/hooks/pre-commit     # 打开配置文件
:set ff-unix                   # 设置文件格式为unix文件,(ff意为fileformat)
:wq                            # 保存修改并退出
@some-code some-code changed the title husky -- 让git hooks更简单的包包 [git hooks] pre-commit 配置 Jun 4, 2018
@kindredPP
Copy link

https://www.cnblogs.com/small-coder/p/9122271.html 在作者的博客文章提了个问题,能帮忙回答一下吗。谢谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants