【问题标题】:Git server hooks, check if code is formatedGit服务器钩子,检查代码是否格式化
【发布时间】:2017-05-07 12:59:16
【问题描述】:

我正在尝试创建一个 git 服务器挂钩,以便不会推送未格式化的代码。在我的场景中,我想使用 clang 格式来检查代码的格式是否正确。如果不是,用户将收到一条消息,说明他们需要在推送之前格式化代码。

我们正在尝试在工作中实施必须格式的政策,这将只是一个安全网。

【问题讨论】:

  • 您能否详细说明您尝试了什么以及失败了什么?

标签: git githooks


【解决方案1】:

在客户端,您可以查看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”查看更多信息

【讨论】:

    【解决方案2】:

    总结

    我花了很长时间才从我能找到的稀疏示例中拼凑起来,所以我想我也会分享我的想法。

    基本上这是你需要做的:

    • 使用update 挂钩(类似于pre-receive
    • 检查分支并提交
    • 将裸仓库签出到临时文件夹
    • 在临时文件夹上运行格式化程序(在本例中为Prettier
    • 如果文件/将被更改,则退出非零
      • (来自工具的输出或git status --work-tree=... --git-dir=...

    示例:Prettier + 'update' Hook

    虽然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 等一样工作。

    更多信息

    我在我写的关于此事的博客文章中提供了更多细节:

    还有更多...

    您也可以从这些其他资源中受益:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-05
      • 2020-05-31
      • 2017-07-12
      • 2019-05-09
      相关资源
      最近更新 更多