Git 远程/共享预提交钩子

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3703159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:06:34  来源:igfitidea点击:

Git remote/shared pre-commit hook

gitgithooks

提问by Samer Buna

With a one official repository as the remote, and multiple local repositories cloned from it, can a pre-commit hook be scripted on that main repository and be enforced on all clones of it?

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

采纳答案by VonC

I don't think so, as hooks are not cloned.
May be if that hook script is itself versioned, and then link to (symbolic link) in the clone servers (provided their OS support that link feature).

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

Or maybe if the hooks are part of a git template directoryused for creating the clones (that would only ensure their presences in the clone repo, that would not guarantee they are actually used and executed).

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

But I don't think there is any "central" way to enforce a commit.

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



As Jefromi explains even more clearly in the comments (emphasis mine):

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

I think it really goes against the idea of a git repository to have enforced hooks distributed with the repo.
My clone is my repository. I should be able to use git on it however I like, including choosing whether or not to run hooks.
(And from a security standpoint, that'd be really kind of scary - no one should have the ability to force me to execute certain scripts whenever I run certain git commands.)

我认为在 git 存储库中强制使用随存储库分发的钩子的想法确实背道而驰。
我的克隆是我的存储库。我应该可以随心所欲地使用 git,包括选择是否运行钩子。
(从安全的角度来看,这真的有点可怕——当我运行某些 git 命令时,没有人应该有能力强迫我执行某些脚本。)

I agree with that comment, and have only seen ways to enforce rules applied locally, in a given specialized repo.
For instance, you wouldn't push to the central repo directly, but would first push to a QA repo which would accept your commit only if it follows certain rules. If it does, then the QA repo will push your commit to the central repo.

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

Another illustration directly derived from what I just mentioned would be "Serverless Continuous Integration with Git", a way to enforce locallyprivate build that works before pushing them anywhere.

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

回答by Jens Timmerman

You can not have the pre-commit hook forcedon peoples local repositories, but in your central repo you can still run a pre-receive hook.

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

F. ex I needed to be sure the commit messages obeyed certain rules (for trac integration etc) so I used following pre-receive hook, which checks every commit messages being pushed to the central repository, and will deny the push if it is not welformed.

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

#!/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 }' )"
    if [ x"$MALFORMED" != x ]
    then
        echo Invallid commit message on $MALFORMED
        exit 1
    fi
done

for more info see f.ex https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

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

回答by bstpierre

can a pre-commit hook be scripted on that main repository and be enforced on all clones of it?

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

From githooks(5):

来自githooks(5)

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

Since the hook can easily be bypassed, it seems the answer to your question is "no".

由于挂钩很容易绕过,因此您的问题的答案似乎是否定的。

Also, since the .git/hooks directory is not cloned, there does not seem to be a mechanism to push it to the client.

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

回答by superluminary

Yes and no.

是和否。

If you are writing JavaScript, the best way to do this is with Husky. Husky has a postInstall script that will set up and manage your githooks. You can then configure precommit and prepush scripts in your package.json or a husky dotfile.

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

You can use this to run arbitrary scripts. I typically yarn lintand yarn testprepush.

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



If you are not using JavaScript, or you cannot use Husky, you can clone commit hooks onto developer machines and check them into a repo, but you cannot force developers to run them.

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

To check in your hooks, create a hooksdirectory somewhere in your repo. Then put your hooks there instead of the usual .git/hooksdirectory. This is the part you can enforce.

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

The other part depends on developer goodwill. To set your hooks folder as the hooksPath, each developer must run:

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

git config core.hooksPath hooks

git config core.hooksPath hooks

Now all the hooks in the hooks folder will run as you would expect.

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

回答by Andrew Wagner

Assuming you have source code in your git repo that has a build system associated with it, you could configure the build system to set up the pre-commit hook, i.e. by moving or linking a pre-commit hook that ~is versioned.

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

I have not tried this yet. I came here while googling for a better solution.

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

回答by Vishrant

I create a new file: pre-commit-hook.sh

我创建一个新文件: 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;

And this is how I commit to Git:

这就是我对 Git 的承诺:

bash pre-commit-hook.sh && git commit -m "<Commit message>"