Git服务器钩子,检查代码格式化

5
我正在尝试创建一个git服务器钩子,以便不会推送未格式化的代码。在我的场景中,我想使用clang格式来检查代码是否正确格式化。如果不是,则用户将收到一条消息,说明他们需要在推送之前格式化代码。
我们正在尝试实施一个必须格式化策略,并且这只是一个安全网。

请问您能否提供更多有关您尝试了什么以及哪些步骤失败的详细信息呢? - Pascal Le Merrer
2个回答

3

3

概要

我花了很长时间从我能找到的零散例子中拼凑出来,所以我想分享我所得到的内容。

基本上你需要做以下几步:

  • 使用一个update钩子(类似于pre-receive
  • 检查分支和提交
  • 将裸仓库检出到临时文件夹中
  • 在临时文件夹中运行格式化工具(在这种情况下是Prettier
  • 如果文件已更改或者会被更改,则退出并返回非零值
    • (可以从工具的输出或者git status --work-tree=... --git-dir=...中获取)

示例:Prettier + 'update' 钩子

虽然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等类似工具。

更多信息

我在博客文章中提供了更详细的说明:

还有更多...

您可能会从以下其他资源中受益:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接