将 Git 挂钩放入存储库
将 .git/hooks 放入项目存储库(例如使用符号链接)是否被认为是一种不好的做法。如果是,向不同的 Git 用户提供相同的 hooks 的最佳方式是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
将 .git/hooks 放入项目存储库(例如使用符号链接)是否被认为是一种不好的做法。如果是,向不同的 Git 用户提供相同的 hooks 的最佳方式是什么?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
现在,您可以执行以下操作将受版本控制的目录设置为 Git hooks 目录,例如, MY_REPO_DIR/.githooks 将会是
它仍然不能直接执行,但是,如果您添加注释在您的自述文件(或其他内容)中,这需要每个开发人员付出最少的努力。
Nowadays you can do the following to set a directory that is under version control to be your Git hooks directory, e.g.,
MY_REPO_DIR/.githooks
would beIt is still not directly enforceable but, if you add a note in your README (or whatever), this requires a minimum of effort on each developer's part.
我总体上同意Scy,还有一些额外的建议,足以值得单独回答。
首先,您应该编写一个脚本来创建适当的符号链接,特别是如果这些挂钩是关于执行策略或创建有用的通知的话。如果人们可以直接输入 bin/create-hook-symlinks ,那么他们将更有可能使用钩子,而不是必须自己执行。
其次,直接符号链接挂钩可以防止用户添加自己的个人挂钩。例如,我更喜欢示例预提交挂钩,它可以确保我没有任何空白错误。解决这个问题的一个好方法是在存储库中放入一个钩子包装脚本,并将所有钩子符号链接到它。
然后,包装器可以检查
$0
(假设它是 Bash 脚本;否则相当于argv[0]
)以找出它被调用的钩子,然后调用适当的钩子存储库中的钩子,以及相应用户的钩子,必须重命名,将所有参数传递给每个钩子。简单示例:安装脚本会将所有预先存在的挂钩移动到一侧(将
.local
附加到其名称),并将所有已知的挂钩名称符号链接到上述脚本:I generally agree with Scy, with a couple of additional suggestions, enough that it's worth a separate answer.
First, you should write a script which creates the appropriate symlinks, especially if these hooks are about enforcing policy or creating useful notifications. People will be much more likely to use the hooks if they can just type
bin/create-hook-symlinks
than if they have to do it themselves.Second, directly symlinking hooks prevents users from adding in their own personal hooks. For example, I rather like the sample pre-commit hook which makes sure I don't have any white space errors. A great way around this is to drop in a hook wrapper script in your repository, and symlink all of the hooks to it.
The wrapper can then examine
$0
(assuming it's a Bash script; an equivalent likeargv[0]
otherwise) to figure out which hook it was invoked as, then invoke the appropriate hook within your repository, as well as the appropriate user's hook, which will have to be renamed, passing all the arguments to each. Quick example:The installation script would move all pre-existing hooks to the side (append
.local
to their names), and symlink all known hook names to the above script:不,将它们放入存储库就可以了。我什至建议这样做(如果它们对其他人也有用)。用户必须显式启用它们(正如您所说,例如通过符号链接),这一方面有点麻烦,但另一方面它可以保护用户在未经用户同意的情况下运行任意代码。
No, putting them into the repository is fine. I’d even suggest doing so (if they are useful for others as well). The user has to explicitly enable them (as you said, for example, by symlinking), which is on one hand a bit of a pain, but it protects users on the other hand from running arbitrary code without their consent.
存储在项目中并安装在构建中
正如其他人在回答中所述,如果您的挂钩特定于您的特定项目,那么将它们包含在由 Git 管理的项目本身中。我想更进一步说,鉴于使用单个脚本或命令构建项目是一种很好的做法,因此应该在构建期间安装您的钩子。
我写了一篇关于管理 Git hooks 的文章,如果你有兴趣的话更深入地阅读有关此内容的内容。
Java& Maven
完全公开;我编写了下面描述的 Maven 插件。
如果您正在处理使用 Maven 为您的 Java 项目进行构建管理,以下 Maven 插件处理从项目中的某个位置安装挂钩。
https://github.com/rudikershaw/git-build-hook
将所有Git 挂钩到项目中的目录中,然后配置
pom.xml
以包含以下插件声明、目标和配置。当您运行项目构建时,插件将配置 Git 以在指定目录外运行挂钩。这将有效地为参与项目的每个人在该目录中设置挂钩。
JavaScript 和NPM
对于 NPM,有一个名为 Husky 的依赖项,它允许您安装钩子,包括用 JavaScript 编写的钩子。
其他
此外,还有许多不同的挂钩管理应用程序/插件,包括 预提交对于 Python 项目,过度提交 对于 Ruby 项目,以及 Leftthook for Ruby 或 Node.js 项目。
Store in the project and install in the build
As others state in their answer, if your hooks are specific for your particular projects then include them in the project itself, managed by Git. I would take this even further and say that, given that it is good practice to have your project build using a single script or command, your hooks should be installed during the build.
I wrote an article about managing Git hooks, if you are interested in reading about this in a little more depth.
Java & Maven
Full disclosure; I wrote the Maven plugin described below.
If you are handling build management with Maven for your Java projects, the following Maven plugin handles installing hooks from a location in your project.
https://github.com/rudikershaw/git-build-hook
Put all your Git hooks in a directory in your project, and then configure your
pom.xml
to include the following plugin declaration, goal, and configuration.When you run your project build, the plugin will configure Git to run hooks out of the directory specified. This will effectively set up the hooks in that directory for everyone working on your project.
JavaScript & NPM
For NPM there is a dependency called Husky which allows you to install hooks including ones written in JavaScript.
Others
Additionally, there are a number of different hook management applications/plugins including pre-commit for Python projects, Overcommit for Ruby projects, and Lefthook for Ruby or Node.js projects.
从 模板目录,您可以使用以下之一这些机制用于更新每个新创建的 Git 存储库的 .git/hooks 目录:
From TEMPLATE DIRECTORY, you could use one of these mechanisms to update the .git/hooks directory of each newly created Git repository:
对于PHP Composer的基于PHP项目,您可以自动分发给工程师。这是预提交和提交消息挂钩的示例。
创建一个
hooks
文件夹,然后在您的 composer.json 文件中:然后您甚至可以在项目继续进行时更新它们,因为每个人都在运行
composer install
定期。For PHP Composer-based PHP projects, you can automatically distribute to engineers. Here is an example for pre-commit and commit-msg hooks.
Create a
hooks
folder, and then in your composer.json file:Then you can even update them as the project continues as everyone is running
composer install
on a regular basis.预提交 npm 包可以优雅地处理这个问题,允许您在 package.json 中指定预提交钩子 em> 文件。
The pre-commit npm package handles this elegantly, allowing you to specify pre-commit hooks in your package.json file.
这是一个脚本 add-git-hook.sh,您可以将其作为存储库中的常规文件发送,并且可以执行该脚本以将 Git 挂钩附加到脚本文件。调整要使用的钩子(预提交、后提交、预推送等)以及 cat heredoc 中钩子的定义。
该脚本可能具有可执行权限或用户可以直接运行它。提交后,我用它在其他机器上自动进行 git-pull。
我回答了一个更简单的问题,这不是所问的问题,也不是OP想要的问题。我在下面的评论中对在存储库中传送钩子脚本与在外部管理它们的用例和参数发表了意见。
Here's a script, add-git-hook.sh, which you can ship as a regular file in the repository and can be executed to append the Git hook to the script file. Adjust which hook to use (pre-commit, post-commit, pre-push, etc.) and the definition of the hook in the cat heredoc.
This script might make sense to have executable permissions or the user can run it directly. I used this to automatically git-pull on other machines after I committed.
I answered the easier question which wasn't what was asked and wasn't what the OP was looking for. I opined on the use cases and arguments for shipping hook scripts in the repository versus managing them externally in the comments below.
看起来很多帖子都已经过时了,至少如果你在 python 生态系统中使用预提交的话(+我发现使用稍旧版本的 git,例如 2.3,更改 git hook 路径会失败)。将 .pre-commit-config.yaml 放在存储库根目录的 hooks 目录中,最简单的解决方案是运行:
Looks like a lot of the posts are out of date, at least if you're using pre-commit in the python ecosystem (+ I found that changing the git hook path fails with slightly older versions of git, e.g. 2.3). With a .pre-commit-config.yaml in a hooks dir in the root of your repo, the easiest solution is to run:
您可以使用托管解决方案进行预提交挂钩管理,例如 预提交。
或者是服务器端 git-hooks 的集中式解决方案,例如 Datree.io。
它具有内置策略,例如:
它不会取代您的所有挂钩,但它可能会帮助您的开发人员使用最明显的挂钩,而无需在每个开发人员的计算机/存储库上安装挂钩的配置地狱。
免责声明:我是 Datrees 创始人之一
You could use a managed solution for pre-commit hook management like pre-commit.
Or a centralized solution for server-side git-hooks like Datree.io.
It has built-in policies like:
It won't replace all of your hooks, but it might help your developers with the most obvious ones without the configuration hell of installing the hooks on every developer's computer/repository.
Disclaimer: I am one of Datrees founders