有了一个官方仓库作为远程仓库,多个本地仓库从它克隆,可以在主仓库上编写一个预提交钩子,并在它的所有克隆上强制执行吗?
vxf3dgd41#
我不这么认为,因为钩子不是克隆的。如果钩子脚本本身是版本化的,然后链接到克隆服务器中的(符号链接)(假设它们的操作系统支持该链接功能),则可能是这样。或者,如果钩子是用于创建克隆的git模板目录的一部分(这只能确保它们存在于克隆存储库中,但不能保证它们实际上被使用和执行)。但我不认为有任何“中心”的方式来强制提交。正如Jefromi在评论中更清楚地解释的那样(强调我的):我认为这真的违背了git仓库的想法,让强制钩子与仓库一起分发。
我的克隆是我的仓库.我应该可以在上面使用git,包括选择是否运行钩子。
(And从安全的Angular 来看,这真的有点可怕-没有人应该有能力在我运行某些git命令时强制我执行某些脚本。我同意这一评论,并且只看到了在给定的专门仓库中强制执行本地应用规则的方法。例如,你不会直接推送到中央仓库,而是会先推送到QA仓库,只有当它遵循某些规则时,它才会接受你的提交。如果它接受了,那么QA仓库会将你的提交推送到中央仓库。另一个例子直接来自我刚才提到的“Serverless Continuous Integration with Git”,一种在将它们推到任何地方之前强制执行 * 本地 * 私有构建的方法。
pb3skfrl2#
你不能在人们的本地仓库上强制预提交钩子,但在你的中央仓库中,你仍然可以运行预接收钩子。
例如,我需要确保提交消息遵守某些规则(用于trac集成等),所以我使用了以下pre-receive钩子,它检查每个被推送到中央存储库的提交消息,如果它不是welformed,它将拒绝推送。
#!/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
xjreopfe3#
两个选项:
如果你正在编写JavaScript,最好的方法是使用Husky。Husky有一个postInstall脚本,可以设置和管理你的githooks。然后你可以在package.json或husky dotfile中配置precommit和prepush脚本。
你可以使用它来运行任意脚本。我通常使用yarn lint和yarn test prepush。
yarn lint
yarn test
如果您没有使用JavaScript,或者您无法使用Husky,您可以将提交钩子克隆到开发人员机器上并将其签入到repo中,但您不能强制开发人员运行它们。
要签入你的钩子,在你的仓库中创建一个hooks目录。然后把你的钩子放在那里,而不是通常的.git/hooks目录。这是你可以强制执行的部分。另一部分取决于开发者的意愿。要将hooks文件夹设置为hooksPath,每个开发者必须运行:git config core.hooksPath hooks现在hooks文件夹中的所有钩子都将按照您所期望的方式运行。
hooks
.git/hooks
git config core.hooksPath hooks
ws51t4hk4#
一个预提交钩子是否可以在主存储库上编写脚本,并在它的所有克隆上强制执行?从githooks(5)开始:
githooks(5)
**pre-commit** This hook is invoked by git commit, and can be bypassed with --no-verify option.
由于钩子可以很容易地被绕过,看来你的问题的答案是“不”。此外,由于.git/hooks目录没有被克隆,因此似乎没有将其推送到客户端的机制。
laximzn55#
这里有非常非常古老的答案。这在今天绝对是可能的。从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,这个配置变量是有用的。这意味着你可以在客户端机器之间共享Git钩子(可能使用项目中的非.git文件夹,或者使用本地克隆的专用Git存储库,或者使用OneDrive或Dropbox等同步软件),只需将core.hooksPath配置设置为该(共享)文件夹即可。
core.hooksPath
$GIT_DIR/hooks
/etc/git/hooks
/etc/git/hooks/pre-receive
$GIT_DIR/hooks/pre-receive
init.templateDir
.git
l7wslrjt6#
假设你的git repo中有一个源代码,并且有一个与之关联的构建系统,你可以配置构建系统来设置pre-commit钩子,即通过移动或链接一个版本化的pre-commit钩子。我还没有试过这个,我是在谷歌寻找更好的解决方案的时候来这里的。
pvabu6sv7#
这不是完全自动的,但你可以在hooks/目录中添加一个仓库的钩子脚本,然后让开发人员在克隆仓库后对钩子脚本进行一次符号链接:
hooks/
ln -s ../../hooks/pre-commit.sh .git/hooks/pre-commit
在项目README中编写文档可能会很好地工作。
qnzebej08#
我创建一个新文件: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;
这就是我对Git的承诺:
bash pre-commit-hook.sh && git commit -m "<Commit message>"
8条答案
按热度按时间vxf3dgd41#
我不这么认为,因为钩子不是克隆的。
如果钩子脚本本身是版本化的,然后链接到克隆服务器中的(符号链接)(假设它们的操作系统支持该链接功能),则可能是这样。
或者,如果钩子是用于创建克隆的git模板目录的一部分(这只能确保它们存在于克隆存储库中,但不能保证它们实际上被使用和执行)。
但我不认为有任何“中心”的方式来强制提交。
正如Jefromi在评论中更清楚地解释的那样(强调我的):
我认为这真的违背了git仓库的想法,让强制钩子与仓库一起分发。
我的克隆是我的仓库.我应该可以在上面使用git,包括选择是否运行钩子。
(And从安全的Angular 来看,这真的有点可怕-没有人应该有能力在我运行某些git命令时强制我执行某些脚本。
我同意这一评论,并且只看到了在给定的专门仓库中强制执行本地应用规则的方法。
例如,你不会直接推送到中央仓库,而是会先推送到QA仓库,只有当它遵循某些规则时,它才会接受你的提交。如果它接受了,那么QA仓库会将你的提交推送到中央仓库。
另一个例子直接来自我刚才提到的“Serverless Continuous Integration with Git”,一种在将它们推到任何地方之前强制执行 * 本地 * 私有构建的方法。
pb3skfrl2#
你不能在人们的本地仓库上强制预提交钩子,但在你的中央仓库中,你仍然可以运行预接收钩子。
例如,我需要确保提交消息遵守某些规则(用于trac集成等),所以我使用了以下pre-receive钩子,它检查每个被推送到中央存储库的提交消息,如果它不是welformed,它将拒绝推送。
更多信息见f.ex https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
xjreopfe3#
两个选项:
1.使用哈士奇
如果你正在编写JavaScript,最好的方法是使用Husky。Husky有一个postInstall脚本,可以设置和管理你的githooks。然后你可以在package.json或husky dotfile中配置precommit和prepush脚本。
你可以使用它来运行任意脚本。我通常使用
yarn lint
和yarn test
prepush。2.在git.config中设置core/hooksPath,然后在repo中包含/hooks
如果您没有使用JavaScript,或者您无法使用Husky,您可以将提交钩子克隆到开发人员机器上并将其签入到repo中,但您不能强制开发人员运行它们。
要签入你的钩子,在你的仓库中创建一个
hooks
目录。然后把你的钩子放在那里,而不是通常的.git/hooks
目录。这是你可以强制执行的部分。另一部分取决于开发者的意愿。要将hooks文件夹设置为hooksPath,每个开发者必须运行:
git config core.hooksPath hooks
现在hooks文件夹中的所有钩子都将按照您所期望的方式运行。
ws51t4hk4#
一个预提交钩子是否可以在主存储库上编写脚本,并在它的所有克隆上强制执行?
从
githooks(5)
开始:由于钩子可以很容易地被绕过,看来你的问题的答案是“不”。
此外,由于.git/hooks目录没有被克隆,因此似乎没有将其推送到客户端的机制。
laximzn55#
这里有非常非常古老的答案。这在今天绝对是可能的。
从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
,这个配置变量是有用的。这意味着你可以在客户端机器之间共享Git钩子(可能使用项目中的非
.git
文件夹,或者使用本地克隆的专用Git存储库,或者使用OneDrive或Dropbox等同步软件),只需将core.hooksPath
配置设置为该(共享)文件夹即可。l7wslrjt6#
假设你的git repo中有一个源代码,并且有一个与之关联的构建系统,你可以配置构建系统来设置pre-commit钩子,即通过移动或链接一个版本化的pre-commit钩子。
我还没有试过这个,我是在谷歌寻找更好的解决方案的时候来这里的。
pvabu6sv7#
这不是完全自动的,但你可以在
hooks/
目录中添加一个仓库的钩子脚本,然后让开发人员在克隆仓库后对钩子脚本进行一次符号链接:在项目README中编写文档可能会很好地工作。
qnzebej08#
我创建一个新文件:
pre-commit-hook.sh
这就是我对Git的承诺: