git hook 通过在代码commit和push之前执行一个脚本,来实现一些检查性工作😎。

在.git/hooks目录下的脚本文件,默认情况下该目录下有以下文件

applypatch-msg.sample

commit-msg:sample

pre-applypatch.sample

pre-commit.sample

pre-push.sample

pre-rebase.sample

prepare-commit-msg.sample


update.sample

pre-receive.sample

post-update:sample

分割线前面几种是客户端钩子,后面几种是服务端钩子

pre-receive可以用来在服务端设置一些代码检查的功能,通过它可以拒绝一些不满足条件的push,无情的推行代

码检查。

post-receive它发生在push代码之后,可以通过CI来触发一些测试代码。

若要相应的钩子生效,编辑脚本文件的内容,去掉.sample后缀即可。脚本若返回非0值,则相应的git操作不再

往后执行。

通过pre-push来举个🌰

现在我想在每次push文件之时,检查项目中有没有重复图片,来减少不必要的包体积。假设检查重复图片的

脚本叫做duplicate_image_detector.py

现在通过客户端钩子来实现,因为./.git/hooks下的文件是无法通过git来进行管理,所以只能在客户端自己将

hook脚本拷贝在./.git/hoos目录下了,hook脚本本身可以通过git来管理。

hook脚本如下:

1
2
3
4
5
6
#!/bin/bash
# 图片检测
if [ ! -f "./Checkers/duplicate_image_detector.py" ]; then
echo "未集成图片检测脚本"
exit 1
fi

如果有多个任务需要处理,下一个任务需要在上一个任务成功之后再执行,则需要通过:

1
$? -eq 0

条件来判断上个任务是否以0结束,以0结束表示执行成功,反之返回非0就代表任务结束,不再继续执行了,

整体类似:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#前置任务
#./abc/xyz/xx.rb

if [ $? -eq 0 ]; then
echo "***********xx.rb检测脚本通过****************"
else
echo "***********xx.rb检测脚本未通过****************"
exit 1
fi

# 图片检测
if [ ! -f "./Checkers/duplicate_image_detector.py" ]; then
echo "未集成图片检测脚本"
exit 1
fi

如果为了进一步方便,再写一个脚本来检查当前环境是否准备好了hook脚本,并进行本地部署:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

if ![-f ./shell/pre-push]; then
echo "没有找到hook的脚本文件"
exit(1)
fi

if [-f ./.git/hooks/pre-push.sample]; then
rm ./.git/hooks/pre-push.sample
fi

cp ./shell/pre-push ./.git/hooks/pre-push

echo "hook设置成功"

每次有新人就让他手动调用一下这个脚本,最好的方式是希望能够将.git/hooks/下的脚本纳入git管理。暂时没有找到解决方案😫,或者部署在服务端,但是需要管理员权限。

针对于上述问题,最后在同事提示下找到一个替换的方案。在Xcode的Build Phases中添加一个”Run Script”功能,在Xcode每次编译的时候都会执行这个脚本。

首先setupHook.sh需要修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash

if [ -f ./shell/pre-push ]; then
echo "hook文件存在"
else
echo "hook文件不存在"
exit 1
fi

if [ -f ./.git/hooks/pre-push.sample ]; then
rm ./.git/hooks/pre-push.sample
fi

if [ -f ./.git/hooks/pre-push ]; then
echo "hook已经设置过"
else
echo "hook未设置,开始设置"
cp ./shell/pre-push ./.git/hooks/pre-push
echo "hook设置成功"
fi

然后再将setupHook.sh脚本添加进去如下所示:

Run Script

还需要修改一下脚本执行权限,在cmd中执行:

1
chmod u+x setupHook.sh

再Build一下,最后会看到如下输出:

log

就说明设置生效了。

这样一来,就不用太担心某个同学因为忘记设置hook脚本而提交代码没有触发脚本的问题了,因为提交代码之前不太可能不会Build代码,但是还是需要在README中显示的提醒一下,最后一步只是以防万一。

参考