Git 服务器挂钩,检查代码是否格式化
Git server hooks, check if code is formated
我正在尝试创建一个 git 服务器挂钩,以便不会推送未格式化的代码。在我的场景中,我想使用 clang 格式来检查代码格式是否正确。如果不是,用户将收到一条消息,说明他们需要在推送之前格式化代码。
我们正在努力在工作中实施必须格式的政策,这只是一个安全网。
在客户端,您可以查看调用 clang-format
以重新格式化 C/C++/Objective-C 源代码的 wangkuiyi/7379a242f0d4089eaa75
which is Git pre-commit
hook。
这让您了解如何编写 server-side pre-receive
hook,它将执行相同的操作并将结果内容与原始内容进行比较。
在“”
查看更多信息
总结
我花了很长时间才从我能找到的稀疏示例中拼凑起来,所以我想我也会分享我的想法。
基本上你需要做的是:
- 使用
update
挂钩(类似于 pre-receive
)
- 检查分支并提交
- 将裸仓库签出到临时文件夹
- 运行 临时文件夹上的格式化程序(Prettier,在本例中)
- 退出 non-zero 如果文件/将被更改
- (来自工具的输出或
git status --work-tree=... --git-dir=...
)
示例:更漂亮 + 'update' 钩子
尽管 pre-receive
挂钩更易于 google 搜索,但我发现 update
挂钩更易于使用且更灵活。我在这个例子中使用了 Prettier,但我试图写成易于适应任何 linter / vetter / 格式化程序。
在我的例子中,我的 git 用户的主目录是 /srv/git-repositories
,我设置的项目挂钩位于:
/srv/git-repositories/my-project.git/hooks/update
我已经实际测试过了,所以我知道它是有效的,尽管它比 I'm really using.
有点淡化了
也就是说,它涵盖了基础知识:
ref_name=
new_rev=
# only check branches, not tags or bare commits
if [ -z $(echo $ref_name | grep "refs/heads/") ]; then
exit 0
fi
# don't check empty branches
if [ "$(expr "${new_rev}" : '0*$')" -ne 0 ]; then
exit 0
fi
# Checkout a copy of the branch (but also changes HEAD)
my_work_tree=$(mktemp -d -t git-work-tree.XXXXXXXX) 2>/dev/null
git --work-tree="${my_work_tree}" --git-dir="." checkout $new_rev -f >/dev/null
# Do the formatter check
echo "Checking code formatting..."
pushd ${my_work_tree} >/dev/null
prettier './**/*.{js,css,html,json,md}' --list-different
my_status=$?
popd >/dev/null
# reset HEAD to master, and cleanup
git --work-tree="${my_work_tree}" --git-dir="." checkout master -f >/dev/null
rm -rf "${my_work_tree}"
# handle error, if any
if [ "0" != "$my_status" ]; then
echo "Please format the files listed above and re-commit."
echo "(and don't forget your .prettierrc, if you have one)"
exit 1
fi
虽然我通常使用 gitea for git hosting, I've tested this particular hook with a simple automated git deploy with ssh,但它应该与 GitLab、Gogs 等一起使用。
更多信息
我在博客中提供了更多细节 post 我就此事写道:
还有更多...
您还可以从其他一些资源中受益:
我正在尝试创建一个 git 服务器挂钩,以便不会推送未格式化的代码。在我的场景中,我想使用 clang 格式来检查代码格式是否正确。如果不是,用户将收到一条消息,说明他们需要在推送之前格式化代码。
我们正在努力在工作中实施必须格式的政策,这只是一个安全网。
在客户端,您可以查看调用 clang-format
以重新格式化 C/C++/Objective-C 源代码的 wangkuiyi/7379a242f0d4089eaa75
which is Git pre-commit
hook。
这让您了解如何编写 server-side pre-receive
hook,它将执行相同的操作并将结果内容与原始内容进行比较。
在“
总结
我花了很长时间才从我能找到的稀疏示例中拼凑起来,所以我想我也会分享我的想法。
基本上你需要做的是:
- 使用
update
挂钩(类似于pre-receive
) - 检查分支并提交
- 将裸仓库签出到临时文件夹
- 运行 临时文件夹上的格式化程序(Prettier,在本例中)
- 退出 non-zero 如果文件/将被更改
- (来自工具的输出或
git status --work-tree=... --git-dir=...
)
- (来自工具的输出或
示例:更漂亮 + 'update' 钩子
尽管 pre-receive
挂钩更易于 google 搜索,但我发现 update
挂钩更易于使用且更灵活。我在这个例子中使用了 Prettier,但我试图写成易于适应任何 linter / vetter / 格式化程序。
在我的例子中,我的 git 用户的主目录是 /srv/git-repositories
,我设置的项目挂钩位于:
/srv/git-repositories/my-project.git/hooks/update
我已经实际测试过了,所以我知道它是有效的,尽管它比 I'm really using.
有点淡化了也就是说,它涵盖了基础知识:
ref_name=
new_rev=
# only check branches, not tags or bare commits
if [ -z $(echo $ref_name | grep "refs/heads/") ]; then
exit 0
fi
# don't check empty branches
if [ "$(expr "${new_rev}" : '0*$')" -ne 0 ]; then
exit 0
fi
# Checkout a copy of the branch (but also changes HEAD)
my_work_tree=$(mktemp -d -t git-work-tree.XXXXXXXX) 2>/dev/null
git --work-tree="${my_work_tree}" --git-dir="." checkout $new_rev -f >/dev/null
# Do the formatter check
echo "Checking code formatting..."
pushd ${my_work_tree} >/dev/null
prettier './**/*.{js,css,html,json,md}' --list-different
my_status=$?
popd >/dev/null
# reset HEAD to master, and cleanup
git --work-tree="${my_work_tree}" --git-dir="." checkout master -f >/dev/null
rm -rf "${my_work_tree}"
# handle error, if any
if [ "0" != "$my_status" ]; then
echo "Please format the files listed above and re-commit."
echo "(and don't forget your .prettierrc, if you have one)"
exit 1
fi
虽然我通常使用 gitea for git hosting, I've tested this particular hook with a simple automated git deploy with ssh,但它应该与 GitLab、Gogs 等一起使用。
更多信息
我在博客中提供了更多细节 post 我就此事写道:
还有更多...
您还可以从其他一些资源中受益: