跟踪.git/hooks中钩子的更改

78

有办法追踪 git 钩子的更改吗?我有三个钩子只在我的机器上显示,其他开发人员 fetch 时没有出现。尝试使用 git add 不起作用。


我也很想知道答案!我无法将描述推送到我的Web服务器。我看到有人建议在受控目录中使用符号链接,指向.git下的文件,但我无法使其工作。 - Robert
可能是重复的问题:Git挂钩脚本是否可以与存储库一起管理? - Cascabel
我投票选择了最早的重复问题进行关闭。这里还有两个链接:https://dev59.com/hnI-5IYBdhLWcg3wBjhR 和 https://dev59.com/FHA75IYBdhLWcg3wH1RB#3464399 一般建议是使用符号链接来管理钩子,可以是整个目录,也可以是单独的钩子,甚至可以像我在这两个链接中提出的那样以更高级的方式操作。 - Cascabel
我已经使用符号链接的方式完成了,但是对于初始克隆,首先需要进行设置。虽然这不是世界末日,但似乎这将是一个不错的功能。 - Hans
2
这就是为什么你要把一个脚本放到代码库里面来管理它,这样在克隆之后只需要一个步骤就可以完成。 - Cascabel
在上述讨论中,我认为应该澄清的一点是:在克隆之后启用钩子之前需要手动操作,这是有意设计的。仅仅因为克隆而自动设置任意代码运行将是巨大的安全风险。 - Mark Adelsberger
6个回答

55

http://benjamin-meyer.blogspot.com/2008/10/git-hooks.html

.git/hooks目录下的文件不属于仓库,因此它们不会被跟踪。一种解决方法是在您的存储库顶部创建一个git_hooks目录,并将.git/hooks链接到git_hooks以便每次克隆时使用。这样钩子将成为项目的一部分,受版本控制并且可以供所有人访问。


编辑:.git/*目录中的文件不属于仓库,因此它们不会被跟踪。 - Jaseem
3
+1 好建议 - 只需记得使用符号链接,但看到git_hooks目录应该是一个好的提醒... - kfmfe04
@kfmfe04 你不需要记住任何东西 :) 只需使用构建脚本即可。 - sobi3ch

26

我知道这个问题已经过了好几年,但我觉得像我这样的旅行者需要知道:按设计,钩子是不被跟踪的!Brian的答案可以解决问题,但问题在于你实际上要相信与你一起工作的每个人都不会在存储库中放入恶意代码,否则你的钩子就会无条件地执行它;这正是安全漏洞的定义。


3
好观点!但是这个问题可以通过将 git_hooks 目录放在完全独立的项目中,只授予对更改负责且具有足够知识的人才能访问该仓库来解决。 - sobi3ch
3
我经常运行rake spec,并相信我没与放置了system("rm -rf / --no-preserve-root")的心理变态者一起工作的人在Rakefile里。我不认为相信我的合作者没有在git hooks中提交恶意代码有什么不同... - lamont
12
我了解提交到代码库的代码可能是恶意的。我运行了单元测试,其中运行了FileUtils.rm_rf(".")来清空我的仓库并完全删除了本地树(也可以轻松地删除我的主目录)。我的观点是git钩子比我每天运行的仓库中的其他成千上万行代码更没有特权。所有这些代码都有能力毁掉我的一天。你能解释一下git钩子和我的单元测试框架及测试之间的根本区别吗? - lamont
@PhilipAdler:如果你只从代码库拉取代码而不执行任何其他操作,则这些钩子将不会被执行。此外,@BrianClapper的解决方案需要你复制或链接“git_hooks”目录。在那之前,你必须检查它的内容。这种方法没有什么失控的情况。 - Damien Flament
2
@PhilipAdler:我并不是说你只能拉取代码!我只是指出“仅拉取”操作不会触发Git钩子。因此,在复制它们之前,您可以自由地检查钩子的内容而不会有任何风险。但确实可以在之后修改这些钩子。因此,链接它们似乎是危险的。但是,在检查它们之前复制它们并不会有风险。 - Damien Flament
显示剩余5条评论

9

恢复这个旧的线程,你可以有一个独立的版本控制目录,其中包含你的钩子,然后使用 git config core.hooksPath 来指定该目录。


4
那么您如何确保团队中的任何人在提交代码之前都进行了这个配置呢? - TangHongWan
2
@PageNotFound,你可以将说明放在项目的README中,并将linting步骤添加到流水线的一个阶段,以防有人忘记时,在构建失败时会被提醒。虽然不是理想的解决方案,但在实践中效果很好。 - emerino

3

修改Brian的答案以考虑Philip的重要观点:

如果您有任何具有写访问权限的用户创建了一个挂钩(比如post-commit),并包含 '#!/bin/sh rm -rf ~' 这样的代码,那么您的主目录就被删除了。(或者可能是更温和但仍然很愚蠢的东西。)

为了防止这种情况发生,最好不要使用符号链接来指向目录,而是手动将它们复制到和从一个git_hooks目录中。是的,当您更新它们时,您必须记住手动复制这些文件,但这总比没有好,而且您仍然不会给某个人在您的机器上授予用户级别的命令访问权限。

更新:如下所述,如果您计划频繁更改挂钩,可以编写一个包装脚本来复制文件,然后运行提交。但是自动化提交(使用git add并输入自动化消息)真的很混乱。更好的想法是让您的其中一个挂钩在提交之前将其复制到此“git_hooks”目录中。这样,恶意用户就无法提交下一个挂钩调用时将运行的文件。


你不需要记住任何东西,只需使用“构建脚本”。然后,如果你有其他想法,可以创建符号链接,复制或采取其他措施。 - sobi3ch

2

使用模板目录。从git克隆中,您可以使用标志--template=<template_directory>将文件添加到$GIT_DIR。您还需要创建一个包含模板的目录或使用git提供的位置/usr/share/git-core/templates。通过使用模板目录,您可以在创建时准备好要在钩子目录中运行的活动钩子。

我不确定您的团队会多频繁地进行编辑,但您可以将此模板保存在所有人都可以访问的存储库中。实际上,这应该是一个钩子,它运行存储库中包含自动运行所需的所有代码的文件。

就像其他人提到的那样,一旦您自动执行未知代码,就会使自己面临风险。


2
另一个解决方案(与跟踪/版本控制无关)可能是使用一个插件来处理钩子函数。
例如: 在Web应用程序的情况下,您可以添加一个脚本到package.json中,该脚本将配置预提交钩子!
以下是一个很好的例子: https://github.com/typicode/husky 最终,这个脚本可以被放在版本控制下,您不必再处理.git文件夹内的钩子。

husky 不是用于 Node.js 项目的吗? - matanster

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