更改默认的Git钩子

46

我不确定Git是否支持这种功能(在我的搜索中没有找到,但我可能使用了错误的词汇),但如果能够修改并启用钩子作为所有新存储库的默认设置(在创建时),那么这将非常有用,因为不需要每次创建新存储库时都进行自定义。似乎最简单的方法是编写一个包装器,在创建新存储库时设置我的钩子并为其授予权限,但如果Git内置了这样的功能,我宁愿使用它,而不是让无关紧要的包装器脚本闲置。


从删除的答案的评论中复制的澄清:

我的问题是是否可以更改ALL新存储库的默认行为,以便它们不需要像每个新存储库那样进行定制。简单的做法是编写用于创建和自定义存储库的包装器(它会生成钩子脚本并赋予它们权限),但似乎应该能够在不这样做的情况下自定义此默认行为。


1
不要忘记答案可以被删除 - 更好的做法通常是澄清你的问题,而不是在答案下添加评论。 - Jonathan Leffler
1
在git 2.9(2016年6月)中,您将拥有一个新的配置项来为所有存储库定义钩子的中心位置:**core.hooksPath**。请参见下面的答案 - VonC
4个回答

45

使用 Git 2.9,您可以使用一个新选项来集中管理钩子:core.hooksPath

请看 提交 867ad08, 提交 de0824e, 提交 bf7d977, 提交 49fa52f (2016年5月4日) 由Ævar Arnfjörð Bjarmason (avar)完成。
(由Junio C Hamano -- gitster --提交 6675f50合并,2016年5月17日)

git config文档现在包括:

core.hooksPath

默认情况下,Git将在“$GIT_DIR/hooks”目录中查找钩子。
将其设置为不同的路径,例如“/etc/git/hooks”,Git将尝试在该目录中查找您的钩子,例如“/etc/git/hooks/pre-receive”,而不是在“$GIT_DIR/hooks/pre-receive”中查找。
路径可以是绝对路径或相对路径。相对路径被视为相对于运行钩子的目录。
这个配置变量在以下情况下非常有用:您希望集中配置Git钩子,而不是在每个仓库上进行配置,或者作为更灵活和集中的替代init.templateDir的选择,在这里您已经更改了默认钩子。
此路径的作者(Ævar Arnfjörð Bjarmason avar)在他的提交中添加了内容:
我打算在一个集中式Git服务器上使用这个功能,用户可以在/gitroot下创建任意存储库,但我希望通过统一的调度机制集中管理应该运行的所有钩子。

Git 2.10使用了新的设置,可以通过git rev-parse --git-path hooks/<hook>命令进行调用。

参见提交记录9445b49 (2016年8月16日) ,作者为Johannes Schindelin (dscho)
(该提交由Junio C Hamano -- gitster --提交记录d05d0e9中合并,时间为2016年8月19日)

rev-parse: 在--git-path中遵循core.hooksPath

该选项的--git-path不仅可以避免一直在路径前加上--git-dir的输出,而且还可以尊重.git目录中特定常见路径的覆盖设置。例如,如果设置了环境变量GIT_OBJECT_DIRECTORYgit rev-parse --git-path objects将报告其值。
引入core.hooksPath设置时,我们忘记相应地调整git_path()。这个补丁修复了这个问题。

6
值得注意的是,这样就防止了2.19版本之后任何.git/hooks的运行。我希望他们能够实现一个更好的备用机制,例如,如果你有.git/hook,就使用它,或者同时运行两个。 - Ciro Santilli OurBigBook.com
这会对服务器端的git hooks产生影响吗?还是只影响客户端的hooks? - DrBeco
@DrBeco 它只影响您执行命令的机器。如果该机器是一个“服务器”(托管存储库的服务器),那么它会影响服务器。如果它是您的机器,一个客户端,那么它会影响客户端。 - VonC
谢谢回复。我应该把我的问题表达得更清楚一些。所以,我有一个服务器,钩子位于两个位置。"服务器"端的钩子位于/srv/git/hooks,而客户端的钩子通常是$GIT_DIR/.git/hooks。我第一次尝试测试时发现,这个命令会统一所有的钩子,并且你将失去同时使用它们的能力。我想知道这是不是真的,或者在这方面是否有其他选择。 - DrBeco
@DrBeco 您的服务器进程应该使用与客户端进程不同的服务帐户运行。这样,每个进程都可以在各自的$HOME/.gitconfig全局Git配置中定义自己的core.hooksPath - VonC
显示剩余2条评论

40

以下内容来自git-init手册页(如果你正在克隆一个现有的仓库而不是从头创建一个新仓库,则也适用于git-clone):

       --template=<template_directory>
           提供将要使用的模板所在的目录。默认的模板目录是 /usr/share/git-core/templates。
当指定了<template_directory>时,它将被用作模板文件的源,代替默认值。模板文件包括一些目录结构、一些建议的“排除模式”和非执行“hook”文件的副本。建议的模式和钩子文件都是可修改和可扩展的。

您可以修改系统范围内的模板目录(默认为/usr/share/git-core/templates,但在您的机器上可能位于不同的位置),您可以在创建或克隆存储库时在命令行中提供--template=<template_directory>, 也可以在配置文件中配置默认的模板目录:

[init]
     templatedir = /path/to/templates

但是钩子文件在新克隆的代码库中最终会变成不可执行的,这一点让人感到放心。 - ndim
但是,如果有人使用自己的git安装或从远程机器克隆(比如通过ssh),那么钩子将不会被复制。 - Pat Notz
没错。这只对在自己的机器上设置默认钩子集合有用。如果你想让团队中的每个人都使用相同的钩子集合,你需要一个包装脚本或类似的东西。 - Brian Campbell

5

在git 1.6.5.3(以及一些早期版本)中,您可以在.git/hooks目录中获取示例钩子:

$ ls .git/hooks
applypatch-msg.sample     post-update.sample        prepare-commit-msg.sample
commit-msg.sample         pre-applypatch.sample     update.sample
post-commit.sample        pre-commit.sample
post-receive.sample       pre-rebase.sample
$ 

它们都可以在我的系统上执行。 要使用其中一个钩子,只需复制或重命名该文件,删除“.sample”后缀。根据需要进行编辑以满足您的要求。


回答评论中的问题-要更改安装的默认示例钩子,您需要找到安装git的目录。在我的计算机上,那是$HOME/git - 因此二进制文件位于$HOME/git/bin/git。然后包含示例钩子的目录为:

$HOME/git/share/git-core/templates/hooks

如果您编辑这些模板(请小心),那么将复制到新的git存储库中的内容就是您所编辑的。它们仍然是示例,但它们将成为您的示例。
我没有尝试在目录中创建非示例文件;它可能会被复制,也可能不会。但是要注意更改默认值-当您升级时,您将不得不重新执行更改。

这也没有回答我提出的问题...请参见我对John Feminella的回复中的澄清,他已经回复了。 - rplevy
2
@rplevy:我可以看到澄清,因为我有足够的声望来查看已删除的答案;其他人不能(包括你)。编辑您的问题以匹配。我认为我的答案确实回答了您的问题,但我有偏见。具体而言,更改安装的默认模板的一种方法是编辑由“git init”复制的文件,这就是我说的。Brian Campbell还指出,有一种方法可以配置“git init”以使用非标准位置,但确保应用非标准选项可能很有趣。您可能需要调查系统配置。 - Jonathan Leffler
谢谢,可能我第一次阅读时误解了你的回答,或者它已经被详细说明了。这确实回答了我的问题。关于“下次升级时,您将不得不重新进行更改”,这取决于情况,我认为apt可能会提示您。而且文件可以分别维护。我想符号链接可能是一个不错的方法。 - rplevy
@rplevy:好的-在规则下面的材料不见了一小段时间;我猜你当时看了答案,没有看到发布后5分钟内完成的更新(所以它不算是发布的编辑)。我不知道apt是否会提示你。符号链接可能有帮助;我不会依赖它而不进行实验,因为我可以看到升级可能会破坏您的修改的多种方式(并且我会将模板放在git控制下!)。 - Jonathan Leffler
1
这个完全有效。它应该得到更多的赞。 - MrPickles

0

对于MacPorts目录将为/opt/local/share/git-core/templates/

为了与团队成员共享钩子或模板,我通常在项目中创建子目录,例如$PROJECT_DIR/lib/git/hooks 然后创建Rake任务或shell脚本 复制cp $PROJECT_DIR/git/hooks/* $PROJECT_DIR/.git/hooks。 符号链接无法工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接