Git远程/共享的预提交挂钩


69

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


5
如果要强制执行,请在中央存储库中使用更新挂钩。如果该挂钩正在执行每次提交验证,则仍可以提供一个预先提交的挂钩;开发人员很可能会自愿采用它,这样他们就可以在做错事时立即发现问题,而不必等到他们尝试去做。
卡斯卡贝尔

Answers:


53

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

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

但是我认为没有任何“中央”方式可以执行提交。


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

我认为这确实违反了git存储库的想法,即必须在存储库中分发强制挂钩。
我的克隆是我的存储库。我应该可以在自己喜欢的地方使用git,包括选择是否运行钩子。
(从安全角度来看,这真的很可怕-任何人都不能在我运行某些git命令时强迫我执行某些脚本。)

我同意这一意见,并且只看到了在给定的专用仓库中执行本地应用规则的方法。
例如,您不会直接推送到中央存储库,而是会先推送到质量检查存储库,仅在遵循某些规则时才会接受您的提交。如果是这样,那么质量检查存储库将把您的提交推送到中央存储库。

从我刚才提到的内容中直接得出的另一个例证是“与Git的无服务器持续集成”,这是一种强制本地私有构建的方法,该方法可以在将它们推到任何地方之前起作用。


7
我认为这确实违反了git存储库的想法,即必须在存储库中分发强制挂钩。我的克隆是我的存储库。我应该可以在自己喜欢的地方使用git,包括选择是否运行钩子。(从安全角度来看,这真的很可怕-任何人都没有能力在我运行某些git命令时强迫我执行某些脚本。)
Cascabel 2010年

1
@Jefromi:你知道什么令人担忧吗?当我输入评论时,在提交编辑的答案之前,我开始输入“ add ...”,并且计算机上的FireFox确实向我提出建议:“添加Jefromi的评论”。显然,这不是我第一次来过;)
VonC


为符号链接提案+1。只要确保至少有一个钩子更新符号链接,并且所有用户要做的就是一次运行它。它仍然是可选的-但是钩子的版本是:-)确实仅对某些类型的环境安全。
WhyNotHugo 2010年

9

您不能将pre-commit钩子强加于人们的本地存储库,但是在中央存储库中,您仍然可以运行pre-receive钩子。

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上回显Invallid提交消息
        1号出口
    科幻
完成

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


7

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

来自githooks(5)

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

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

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


7

是的,没有。

如果您正在编写JavaScript,那么最好的方法就是使用Husky。Husky具有postInstall脚本,该脚本将设置和管理您的githooks。然后,您可以在package.json或沙哑的点文件中配置预提交和预推送脚本。

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


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

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

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

git config core.hooksPath hooks

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


2

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

我还没有尝试过。我是在谷歌搜索时寻求更好的解决方案的。


-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>"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.