74

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

4

6 回答 6

53

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

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

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


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

我认为它确实违背了 git 存储库与 repo 一起分发的强制钩子的想法。
我的克隆是我的存储库。我应该可以随意使用 git,包括选择是否运行钩子。
(从安全的角度来看,这真的有点可怕——当我运行某些 git 命令时,没有人应该有能力强迫我执行某些脚本。)

我同意该评论,并且只看到了在给定的专门回购中执行本地应用规则的方法。
例如,您不会直接推送到中央仓库,而是首先推送到 QA 仓库,该仓库只有在遵循某些规则时才会接受您的提交。如果是这样,那么 QA 存储库会将您的提交推送到中央存储库。

另一个直接源自我刚才提到的示例是“与 Git 的无服务器持续集成”,这是一种在将它们推送到任何地方之前强制执行本地私有构建的方法。

于 2010-09-13T18:16:23.903 回答
9

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

F. ex 我需要确保提交消息遵守某些规则(用于 trac 集成等)所以我使用了以下 pre-receive 钩子,它检查每个提交消息被推送到中央存储库,如果不是,将拒绝推送欢迎。

#!/bin/sh
同时读取 rev_old rev_new ref
做
    MALFORMED="$(git rev-list --oneline $rev_old..$rev_new | egrep -v '#[0-9]+' | awk '{print $1}' )"
    如果 [ x"$MALFORMED" != x ]
    然后
        在 $MALFORMED 上回显无效提交消息
        1号出口
    菲
完毕

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

于 2012-01-05T09:06:08.053 回答
8

是和不是。

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

您可以使用它来运行任意脚本。我通常会yarn lint预先yarn test推送。


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

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

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

git config core.hooksPath hooks

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

于 2018-03-20T12:06:19.770 回答
6

可以在该主存储库上编写预提交挂钩脚本并在它的所有克隆上强制执行吗?

来自githooks(5)

    预提交
      这个钩子由 git commit 调用,可以绕过
      --no-verify 选项。

由于可以轻松绕过钩子,因此您的问题的答案似乎是“否”。

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

于 2010-09-13T18:14:32.623 回答
2

假设您的 git 存储库中的源代码具有与之关联的构建系统,您可以配置构建系统以设置预提交挂钩,即通过移动或链接〜已版本化的预提交挂钩。

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

于 2012-08-03T17:09:27.840 回答
-1

我创建一个新文件: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>"
于 2019-01-29T15:54:19.390 回答