Git远程/共享预提交钩子

问题描述 投票:64回答:6

使用一个官方存储库作为远程数据库,并从中克隆多个本地存储库,是否可以在该主存储库上编写预提交钩子并在其所有克隆上强制执行?

git githooks
6个回答
49
投票

我不这么认为,因为没有克隆钩子。 可能是因为该钩子脚本本身是版本化的,然后链接到克隆服务器中的(符号链接)(假设他们的操作系统支持该链接功能)。

或者,如果钩子是用于创建克隆的git template directory的一部分(这只会确保它们存在于克隆存储库中,这不能保证它们实际上被使用和执行)。

但我认为没有任何“中心”方式来强制执行提交。


正如Jefromi在评论中更清楚地解释(强调我的):

我认为这实际上违背了git存储库的想法,即使用repo分发强制挂钩。 我的克隆是我的存储库。我应该可以在它上面使用git,包括选择是否运行钩子。 (从安全的角度来看,这确实很可怕 - 每当我运行某些git命令时,没有人能够强迫我执行某些脚本。)

我同意这一评论,并且只看到了在给定的专业回购中强制执行本地规则的方法。 例如,您不会直接推送到中央仓库,而是首先推送到QA仓库,只有遵循某些规则才能接受您的承诺。如果确实如此,则QA repo会将您的提交推送到中央仓库。

直接源自我刚才提到的另一个例子是“Serverless Continuous Integration with Git”,这是一种强制执行本地私有构建的方法,可以在将它们推送到任何地方之前工作。


8
投票

您不能在人员本地存储库上强制执行预提交挂钩,但在您的中央存储库中,您仍然可以运行预接收挂钩。

F. ex我需要确保提交消息遵循某些规则(用于trac集成等)所以我使用了以下预接收挂钩,它检查被推送到中央存储库的每个提交消息,并且如果不是则拒绝推送welformed。

#!/bin/sh
while read rev_old rev_new ref
do
    MALFORMED="$(git rev-list --oneline $rev_old..$rev_new | egrep -v '#[0-9]+' |  awk '{print $1}' )"
    if [ x"$MALFORMED" != x ]
    then
        echo Invallid commit message on $MALFORMED
        exit 1
    fi
done

有关更多信息,请参阅f.ex https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks


7
投票

是否可以在该主存储库上编写预提交钩子并在其所有克隆上强制执行?

来自githooks(5)

    pre-commit
      This hook is invoked by git commit, and can be bypassed with
      --no-verify option.

由于钩子很容易被绕过,所以你的问题的答案似乎是“不”。

此外,由于未克隆.git / hooks目录,因此似乎没有将其推送到客户端的机制。


5
投票

是的,不是。

如果您正在编写JavaScript,最好的方法是使用Husky。赫斯基有一个postInstall脚本,可以设置和管理你的githooks。然后,您可以在package.json中配置precommit和prepush脚本。

您可以使用它来运行任意脚本。我通常npm run lintnpm test prepush


如果您不使用JavaScript,或者您不能使用Husky,则可以将提交挂钩克隆到开发人员计算机上并将其检入到存储库中,但是您无法强制开发人员运行它们。

要检查您的钩子,请在您的仓库中的某个位置创建一个hooks目录。然后把你的钩子放在那里,而不是通常的.git/hooks目录。这是您可以执行的部分。

另一部分取决于开发人员的善意。要将hooks文件夹设置为hooksPath,每个开发人员必须运行:

git config core.hooksPath hooks

现在,hooks文件夹中的所有钩子都将按预期运行。


2
投票

假设你的git仓库中有源代码,它有一个与之关联的构建系统,你可以配置构建系统来设置预提交钩子,即通过移动或链接〜版本化的预提交钩子。

我还没试过这个。谷歌搜索更好的解决方案时,我来到这里。


0
投票

我创建了一个新文件:pre-commit-hook.sh

#!/usr/bin/env bash
CHANGES=$(git whatchanged ..origin)

if [ ! -z "${CHANGES}" ]; then
    echo "There are changes in remote repository. Please pull from remote branch first."
    exit 1;
fi

exit 0;

这就是我对Git的承诺:

bash pre-commit-hook.sh && git commit -m "<Commit message>"
© www.soinside.com 2019 - 2024. All rights reserved.