我正在尝试创建一个git服务器钩子,以便不会推送未格式化的代码。在我的场景中,我想使用clang格式来检查代码是否正确格式化。如果不是,则用户将收到一条消息,说明他们需要在推送之前格式化代码。
我们正在尝试实施一个必须格式化策略,并且这只是一个安全网。
我们正在尝试实施一个必须格式化策略,并且这只是一个安全网。
wangkuiyi/7379a242f0d4089eaa75
,这是一个Git pre-commit
hook,它调用clang-format
来重新格式化C/C++/Objective-C源代码。pre-receive
hook的想法,它将执行相同的操作并将结果内容与原始内容进行比较。我花了很长时间从我能找到的零散例子中拼凑出来,所以我想分享我所得到的内容。
基本上你需要做以下几步:
update
钩子(类似于pre-receive
)git status --work-tree=... --git-dir=...
中获取)虽然pre-receive
钩子更容易在Google中搜索到,但我发现update
钩子更容易使用和更灵活。在这个例子中,我使用了Prettier,但我尝试着编写它,以便适应任何代码检查器/格式化器。
在我的情况下,我的git用户的主目录是/srv/git-repositories
,我设置的项目钩子位于:
/srv/git-repositories/my-project.git/hooks/update
我已经测试过这个方法,所以我知道它是可行的,尽管它不如我的真正使用方式那么完美。
话虽如此,它涵盖了基本内容:
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托管,但我已经使用一个简单的ssh自动化git部署测试了这个特定的钩子,并且它应该也适用于GitLab、Gogs等类似工具。
我在博客文章中提供了更详细的说明:
您可能会从以下其他资源中受益: