【发布时间】:2017-05-07 12:59:16
【问题描述】:
我正在尝试创建一个 git 服务器挂钩,以便不会推送未格式化的代码。在我的场景中,我想使用 clang 格式来检查代码的格式是否正确。如果不是,用户将收到一条消息,说明他们需要在推送之前格式化代码。
我们正在尝试在工作中实施必须格式的政策,这将只是一个安全网。
【问题讨论】:
-
您能否详细说明您尝试了什么以及失败了什么?
我正在尝试创建一个 git 服务器挂钩,以便不会推送未格式化的代码。在我的场景中,我想使用 clang 格式来检查代码的格式是否正确。如果不是,用户将收到一条消息,说明他们需要在推送之前格式化代码。
我们正在尝试在工作中实施必须格式的政策,这将只是一个安全网。
【问题讨论】:
在客户端,您可以查看wangkuiyi/7379a242f0d4089eaa75,它是Git pre-commit hook,它调用clang-format 以重新格式化C/C++/Objective-C 源代码。
这让您了解如何编写 server-side pre-receive hook,它会执行相同的操作并将生成的内容与原始内容进行比较。
在“Git 'pre-receive' hook and 'git-clang-format' script to reliably reject pushes that violate code style conventions”查看更多信息
【讨论】:
我花了很长时间才从我能找到的稀疏示例中拼凑起来,所以我想我也会分享我的想法。
基本上这是你需要做的:
update 挂钩(类似于pre-receive)git status --work-tree=... --git-dir=...)虽然pre-receive 钩子更易于搜索,但我发现update 钩子更易于使用且更灵活。我在这个例子中使用了 Prettier,但我试图写得容易适应任何 linter / vetter / formatter。
在我的情况下,我的 git 用户的主目录是 /srv/git-repositories,我设置的项目的挂钩位于:
/srv/git-repositories/my-project.git/hooks/update
我实际上已经对此进行了测试,所以我知道它可以工作,尽管它与 I'm really using 相比有点淡化了。
也就是说,它涵盖了基础知识:
ref_name=$1
new_rev=$3
# 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 来托管 git,但我已经使用简单的 automated git deploy with ssh 测试了这个特殊的钩子,它应该与 GitLab、Gogs 等一样工作。
我在我写的关于此事的博客文章中提供了更多细节:
您也可以从这些其他资源中受益:
【讨论】: