Git远程/共享预提交钩子

时间:2010-09-13 18:10:20

标签: git githooks

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

6 个答案:

答案 0 :(得分:49)

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

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

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


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

  

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

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

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

答案 1 :(得分:8)

您不能在人口本地存储库中使用预提交挂钩,但在您的中央存储库中,您仍然可以运行预接收挂钩。

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

#!/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

答案 2 :(得分:7)

  

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

来自githooks(5)

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

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

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

答案 3 :(得分:5)

是和否。

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

您可以使用它来运行任意脚本。我通常会npm run lintnpm test预先准备

如果你没有使用JavaScript ,或者你不能使用Husky,你可以将提交钩子克隆到开发者机器上并将它们检入一个仓库,但你不能强迫开发人员运行它们。

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

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

git config core.hooksPath hooks

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

答案 4 :(得分:2)

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

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

答案 5 :(得分: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>"