挂钩类型可从Git存储库中排除文件类型

时间:2018-12-11 13:34:36

标签: git gitlab githooks

我正在尝试编写git钩子,以防止将.exe文件等文件推送到存储库中。

我们使用Gitlab进行源代码控制,此钩子将代替Gitlab“禁止的文件名”推送规则。

我的问题是:我应该写哪种类型的挂钩?

我走了写预接收钩子的路。听起来不错吗?

谢谢

塞恩

2 个答案:

答案 0 :(得分:2)

将文件排除在检入源代码控制之外的最佳方法是通过.gitignore

但是,如果您真的想编写一个钩子,则在这种情况下(即,在将其推入遥控器之前先做一些事情)最合适的钩子是“预推”钩子。

答案 1 :(得分:2)

在服务器上,有两个选项,分别是 pre-receive update 挂钩。 (对于这种特殊情况,我可能会自己使用更新钩子。)

一次调用预接收钩子,将标准输入连接到包含所有建议的参考更新的管道。您应该阅读所有stdin行,并使用新旧哈希ID和所有引用的名称来确定是否允许进行 entire 推送或 entire 推送-所有名称更新-都将被立即拒绝。也就是说,假设某些客户端已运行:

git push origin hash1:name1 hash2:name2 ... hashN:nameN

以便在stdin的 N 行上有 N 个更新请求,您的pre-receive钩子要么全部接受,要么全部拒绝。要接受全部,请以零状态退出;禁止所有,以任何非零状态退出。如果您退出非零值,则打印原因作为拒绝的好主意,以便客户端可以看到您为什么这样做。

在预接收挂钩(如果有)允许整个过程进入第二阶段之后,每个建议的更新都会调用一次更新挂钩。它具有三个 positional 参数,它们提供与到预接收钩子的输入行之一相同的信息。您应该检查两个哈希ID和名称,并确定是否允许此特定更新

也就是说,给定相同的客户端调用,您的更新挂钩将分别被 N 次调用。例如,第二个将具有:

$1: refs/heads/name2
$2: the old hash ID (or the all-zeros "null hash")
$3: the new hash ID (or all-zeros)

如果您愿意将name2设置为指向新的哈希ID,请使更新挂钩退出状态为零(成功)。如果不是,则以非零状态退出。同样,如果您要拒绝更新,则最好打印一些内容。

关于一般的服务器端挂钩

您的钩子会按引用接收旧的哈希ID(下面的$old),新的哈希ID($new)和引用的全名:{如果引用是分支名称,则为{1}};如果它是标记名称,则为refs/heads/name;如果是注释引用,则为refs/tags/name,依此类推。更新挂钩具有更精细的粒度,但无法整体看到建议的更新。

refs/notes/name$old中的一个最多为全零。如果是这样,则将创建引用(例如,创建新的分支或标记)或将其销毁。否则,它是就地更新:引用当前指向哈希ID $new,运行$old的人建议将其更改为指向哈希ID {{1 }}。

这些钩子非常有效,但是很难编写。特别是,如果引用正在更新,则很清楚该怎么做:更新将在git push范围内添加提交,因此:

$new

足以让您检查每个建议的 new 提交的内容。 (某些提交可能已被删除,可以通过检查$old..$new找到这些提交。)

但是,如果引用是新创建的,则git rev-list $old..$new | while read rev; do # examine the files in $rev done 将为全零。不能肯定地确定仅由该特定参考文献新引入了哪些参考文献。您可以使用此技巧:

$new..$old

枚举可从提议的新参考中获得的提交,但不能从任何当前参考中获得。但是,这可能会产生误导:也许推送是创建三个新分支名称的请求:

$old

孤立地来看,将git rev-list $new --not --all 设置为指向其哈希ID为...--o--o--o <-- master \ A--B <-- newbranch1 \ C <-- newbranch2 \ D--E--F <-- newbranch3 的提交的请求看起来像是添加所有六个提交的请求(实际上是!),但您可能更喜欢例如,将 view 作为请求仅在其他添加的分支newbranch3之后添加三个提交。无法在更新挂钩中生成此视图。可以(但很难)在预接收挂钩中生成它,因为它可以告诉我们三个F名称都是新的。