我们想制作一些我们都可以共享的基本钩子脚本——例如预先格式化提交消息。Git 具有通常存储在<project>/.git/hooks/
. 但是,当人们进行克隆并且它们不受版本控制时,这些脚本不会传播。
有没有什么好方法可以帮助大家获取正确的钩子脚本?我可以让这些钩子脚本指向我的仓库中的版本控制脚本吗?
在Git 2.9中,配置选项core.hooksPath
指定了一个自定义钩子目录。
将您的挂钩移动到hooks
存储库中的跟踪目录。然后,将存储库的每个实例配置为使用 trackedhooks
而不是$GIT_DIR/hooks
:
git config core.hooksPath hooks
一般来说,路径可以是绝对的,也可以是相对于运行钩子的目录(通常是工作树的根目录;参见 描述部分man githooks
)。
从理论上讲,您可以hooks
在项目目录中创建一个包含所有脚本的目录(或您喜欢的任何名称),然后将它们符号链接到.git/hooks
. 当然,每个克隆 repo 的人都必须设置这些符号链接(尽管您可能会非常喜欢并拥有一个克隆器可以运行的部署脚本来半自动地设置它们)。
要在 *nix 上进行符号链接,您需要做的就是:
root="$(pwd)"
ln -s "$root/hooks" "$root/.git/hooks"
ln -sf
如果您准备好覆盖其中的内容,请使用.git/hooks
对于Node.js用户,一个简单的解决方案是更新package.json
{
"name": "name",
"version": "0.0.1",
......
"scripts": {
"preinstall": "git config core.hooksPath hooks",
预安装将在之前运行
npm 安装
并重定向 Git 以在.\hooks(或您选择的任何名称)目录中查找挂钩。这个目录应该在文件名(减去 .sample)和结构方面模仿.\.git\hooks 。
想象一下Maven和其他构建工具将具有与preinstall等效的功能。
它也应该适用于所有平台。
如果您需要更多信息,请参阅与团队共享 Git 挂钩的两种方法。
如果您的项目是 JavaScript 项目并且您npm
用作包管理器,则可以使用shared-git-hooks在npm install
.
完全披露:我写了这个包
大多数现代编程语言,或者更确切地说是它们的构建工具,都支持插件来管理 Git 挂钩。这意味着您需要做的就是配置您的package.json、pom.xml等文件,您团队中的任何人都别无选择,只能遵守,除非他们更改构建文件。
该插件将为您将内容添加到 .git 目录。
例子:
使用git-hooks。它将调用路由.git/hooks
到项目目录下的脚本中,githooks
.
还有很多功能可以让您在各处最小化复制和符号链接挂钩。
我们正在使用具有构建前和构建后事件的 Visual Studio 解决方案(以及项目)。我正在添加一个名为“GitHookDeployer”的附加项目。项目在构建后事件中自行修改文件。该文件设置为复制到构建目录。因此,该项目每次都构建并且永远不会被跳过。在构建事件中,它还确保所有 git 挂钩都到位。
请注意,这不是一个通用的解决方案,因为某些项目当然没有什么可构建的。
您可以使用托管解决方案进行预提交挂钩管理,例如pre-commit。或者像Datree.io这样的服务器端 git-hooks 的集中式解决方案。它具有内置策略,例如:
它不会取代您所有的钩子,但它可能会帮助您的开发人员使用最明显的钩子,而无需在每台开发人员计算机/存储库上安装钩子的配置地狱。
免责声明:我是 Datrees 的创始人之一
您可以将您的钩子文件夹设为另一个 Git 存储库并将其链接为子模块...
我想只有当你有很多成员和钩子定期更换时才值得。
理想情况下,如果您遵循示例文件,挂钩是用 Bash 编写的。但是您可以用任何可用的语言编写它,并确保它具有可执行标志。
因此,您可以编写 Python 或 Go 代码来实现您的目标,并将其放在 hooks 文件夹下。它可以工作,但不会与存储库一起管理。
两种选择
a) 多脚本
你可以在你的帮助中编写你的钩子,并在钩子中添加一小段代码,以调用你的完美脚本,如下所示:
$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/myprecommit.js
b) 单一脚本
一个更酷的选择是只添加一个脚本来统治它们,而不是几个。因此,您创建了一个hooks/mysuperhook.go文件并将每个您想要的钩子指向它。
$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/mysuperhook.go $(basename $0)
该参数将为您的脚本提供触发了哪个钩子,您可以在代码中区分它。为什么?例如,有时您可能希望对提交和推送运行相同的检查。
进而?
然后,您可能希望拥有更多功能,例如:
这可以更简单吗?
是的,有几个工具可以帮助您管理 Git 挂钩。它们中的每一个都是为从不同的角度解决问题而量身定制的,您可能需要了解所有这些才能获得最适合您或您的团队的一个。GitHooks.com提供了很多关于 hooking 的阅读,以及一些当今可用的工具。
截至今天,这里列出了 21 个项目,它们使用不同的策略来管理 Git 挂钩。有些只针对单个钩子,有些针对特定语言,等等。
其中一个由我编写并作为开源项目免费提供的工具称为hooks4git。它是用 Python 编写的(因为我喜欢它),但想法是在一个名为.hooks4git.ini的单个配置文件中处理上面列出的所有项目,该文件位于您的存储库中,并且可以调用任何您想调用的任何脚本语言。
使用 Git 钩子绝对很棒,但提供它们的方式通常只会让人们远离它。
我发现这些脚本对 Gradle 项目非常有用。
apply from: rootProject.file('gradle/install-git-hooks.gradle')
tasks.create(name: 'gitExecutableHooks') {
doLast {
Runtime.getRuntime().exec("chmod -R +x .git/hooks/");
}
}
task installGitHooks(type: Copy) {
from new File(rootProject.rootDir, 'pre-commit')
into { new File(rootProject.rootDir, '.git/hooks') }
}
gitExecutableHooks.dependsOn installGitHooks
clean.dependsOn gitExecutableHooks
.... your pre commit scripts goes here
我想将几个答案合并为一个。假设您在您的project/
目录中:
创建.githooks
目录并将钩子放在其中。(参见.git/hooks
示例)
创建一个.gitconfig
指向目录¹的文件:
git config -f .gitconfig core.hooksPath .githooks
在您的²中创建以下规则Makefile
:
enable-git-hooks:
git config --local include.path ../.gitconfig
$(warning REMEMBER, YOU MUST HAVE REVIEWED THE CUSTOM HOOKS!)
每个开发人员都应该在查看这些自定义挂钩后明确启用它们。在您的 README 中添加一个指令,如下所示:
启用自定义挂钩后通过
make enable-git-hooks
.
我目前正在我们的代码库中处理这个问题,我遇到了一个名为的库husky
,它简化了如何在您的团队中使用和共享 GitHub Hooks。我强烈建议调查一下。