如何将预提交钩子推送到所有现有存储库

时间:2019-08-21 15:11:53

标签: git github githooks

在GHE(GitHub企业版)中,是否可以在所有现有(和新)存储库中共享预提交钩子?例如,我想首先拒绝提交的JKS文件。

我知道这些可以绕开,只是想让做错事情变得更加困难。

1 个答案:

答案 0 :(得分:1)

无法完成您所要求的操作。

首先,没有将挂钩作为存储库的一部分进行传输。由于它们可以执行任意代码,因此Git没有提供将其作为存储库的一部分进行传输或自动更改它们的方法。您可以在存储库中包含一组挂钩,但是是否安装挂钩取决于用户(或构建系统的一部分)。通常,用户会在开发过程中使用自定义钩子,而您的构建系统会覆盖这些钩子。

第二,GitHub提供了模板机制,但没有提供在所有新存储库中自动安装文件的方法。即使他们这样做了,对于用户来说,推入一个新的存储库也可以轻松地将其推入数据库。

第三,要修改所有现有存储库,您需要在每个存储库中进行一次提交。您可以使用API​​编写脚本,但是它需要每个存储库的权限,因此您必须是管理员才能执行此操作。而且如前所述,您仍然必须为每个钩子安装一个方法。

您可以 要做的是在服务器上use a pre-receive hook(为所有存储库启用),该服务器拒绝包含这些文件的推送。由于这些文件可以使用任何名称,因此您可能需要遍历所推送的每个提交中的每个blob,并查看其是否以适当的魔术字节序列开头。如果您对查找文件模式感到满意,则可以执行以下操作:

#!/bin/sh -e

while read old new ref
do
    # Deleted ref.
    if echo "$new" | grep -qsE '^0+$'
    then
        continue
    fi

    if echo "$old" | grep -qsE '^0+$'
    then
        # Newly created ref.
        start=
    else
        # Updated ref.
        start="$old.."
    fi
    git rev-list "$start$new" | (while read rev
    do
        output=$(git ls-tree -r --name-only "$rev" | grep '.jks$') || true
        if [ -n "$output" ]
        then
            echo "Revision $rev from $ref contains forbidden files:"
            echo "$output"
            exit 1
        fi
    done)
done