一个官方代码仓库作为远程仓库,多个本地代码仓库从它克隆而来,能否在主仓库上编写并执行预提交钩子,并将其强制应用于所有克隆仓库?
一个官方代码仓库作为远程仓库,多个本地代码仓库从它克隆而来,能否在主仓库上编写并执行预提交钩子,并将其强制应用于所有克隆仓库?
或者,如果钩子是git模板目录的一部分,用于创建克隆(这只能确保它们存在于克隆仓库中,但不能保证它们实际上被使用和执行)。
但我认为没有任何“集中”的方法来强制执行提交。
正如Jefromi在评论中更清楚地解释的那样(重点是我的):
我认为,强制分发存储库的挂钩真的违反了git存储库的思想。
我的克隆是我的存储库。我应该能够根据自己的喜好使用它上面的git,包括选择是否运行挂钩。
(从安全角度来看,这将非常可怕 - 没有人应该有能力强制我在运行某些git命令时执行某些脚本。)
我同意这个评论,并且只看到了在给定的专业存储库中强制实施规则的方法。
例如,您不会直接推送到中央存储库,而是首先推送到QA存储库,只有在遵循某些规则的情况下,QA存储库才会接受您的提交。如果是这样,则QA存储库将推送您的提交到中央存储库。
另一个直接来源于我刚才提到的例子的插图是 "Serverless Continuous Integration with Git",这是一种在任何地方推送之前强制执行本地私有构建的方法。
#!/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更多信息请参见 https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks。
两种选择:
如果你正在编写JavaScript代码,最好的方法是使用Husky。 Husky有一个postInstall脚本,可以设置和管理githooks。然后,您可以在package.json或husky dotfile中配置precommit和prepush脚本。
您可以使用此选项来运行任意脚本。 我通常会使用yarn lint
和 yarn test
prepush。
如果您没有使用JavaScript,或者您无法使用Husky,则可以将提交挂钩克隆到开发人员机器上并将其检入存储库,但您无法强制开发人员运行它们。
要检入钩子,请在存储库的某个位置创建一个hooks
目录。 然后,将您的挂钩放在那里而不是通常的.git/hooks
目录中。 这部分是您可以强制执行的。
另一部分取决于开发人员的良心。 每个开发者都必须运行以下命令才能将您的挂钩文件夹设置为hooksPath:
git config core.hooksPath hooks
现在,hooks文件夹中的所有挂钩都将按预期运行。
core.hooksPath
可以在post-checkout
钩子中设置吗?这样,它将在克隆后运行。 - MS Berends能否在主代码库上编写一个pre-commit hook,并强制执行所有克隆的副本?
来自githooks(5)
:
pre-commit 此挂钩由git commit调用,并可使用--no-verify选项绕过。
由于该挂钩可以轻松绕过,因此似乎答案是否定的。
另外,由于.git/hooks目录未被克隆,因此似乎没有将其推送到客户端的机制。
这里的答案很老旧。如今,这绝对是可行的。
自Git 2.9以来,配置core.hooksPath
已经可用。根据git文档:
core.hooksPath
默认情况下,Git会在
$GIT_DIR/hooks
目录中寻找钩子。将其设置为不同的路径,例如/etc/git/hooks
,Git将尝试在该目录中查找您的钩子,例如/etc/git/hooks/pre-receive
,而不是在$GIT_DIR/hooks/pre-receive
中查找路径可以是绝对或相对的。相对路径被视为相对于运行钩子的目录(请参见githooks[5]的“描述”部分)。
在以下情况下,此配置变量非常有用:您希望集中配置Git钩子,而不是按存储库进行配置;或者作为init.templateDir的更灵活和集中的替代方案,在那里您已更改了默认钩子。
这意味着,您只需将core.hooksPath
设置为该(共享)文件夹,便可以在客户端机器之间共享Git hooks(可能使用项目内非.git
文件夹、本地克隆的专用Git存储库或使用OneDrive或Dropbox等同步软件)。
ln -s ../../hooks/pre-commit.sh .git/hooks/pre-commit
(据我所知,这一直是可能的)和git config core.hooksPath hooks/
之间没有太大区别。用户仍然需要知道他们需要设置它。 - Alexander Klimetschekgit config
是可行的。 - MS Berends这并不是完全自动化的,但你可以为一个存储库添加钩子脚本,放在一个名为hooks/
的目录中,并将其添加到git中。然后要求开发人员在克隆存储库后创建钩子脚本的符号链接:
ln -s ../../hooks/pre-commit.sh .git/hooks/pre-commit
在项目的 README 文件中记录可能已经足够好了。
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>"