如何将git钩子重新加载到模板钩子

如何将git钩子重新加载到模板钩子,git,templates,github,gitlab,hook,Git,Templates,Github,Gitlab,Hook,我已经编辑了一些预先存在的钩子,并希望将它们设置为克隆存储库时的默认钩子。当我克隆一个新项目时,我可以看到我的挂钩可用。因为我不想重新克隆我所有的项目,所以我希望能够将git模板重新加载到现有的项目中。我在.git所在的同一目录中运行了git init,但钩子从未覆盖我所在项目中预先存在的钩子。有人知道如何将模板挂钩重新加载到现有的克隆项目上吗?因为.git本身中的文件没有版本控制,git也不知道,例如,一些现有的.git/hooks/pre-commit文件实际上是从一些早期的模板安装的,Gi

我已经编辑了一些预先存在的钩子,并希望将它们设置为克隆存储库时的默认钩子。当我克隆一个新项目时,我可以看到我的挂钩可用。因为我不想重新克隆我所有的项目,所以我希望能够将git模板重新加载到现有的项目中。我在
.git
所在的同一目录中运行了
git init
,但钩子从未覆盖我所在项目中预先存在的钩子。有人知道如何将模板挂钩重新加载到现有的克隆项目上吗?

因为
.git
本身中的文件没有版本控制,git也不知道,例如,一些现有的
.git/hooks/pre-commit
文件实际上是从一些早期的模板安装的,Git不会用更新模板中的新文件覆盖现有文件

有一种方法可以解决这个问题,但至少有一次会有点痛。这是:对于某些
name
,您不必在
.git/hooks/name
中使用“真正的”钩子,而是作为
.git/hooks/name
安装间接到真正钩子的东西

在Unix ish系统上,这非常简单,只需将
.git/hooks/name
作为指向所需钩子的符号链接,该钩子就可以位于文件系统中的任何位置。在其他系统上,如果
.git/hooks/name
中必须有一个可执行文件,则可以将
.git/hooks/name
制作为单行可执行shell脚本(通常有两行),例如:

然后“真正的”钩子又一次可以生活在任何地方

关于相对路径的旁注 此特定示例使用绝对路径。相对路径是可能的,但您必须注意相对路径

如果您可以使用符号链接,您知道您是相对于
.git/hooks
目录本身进行链接的,因此从
.git/hooks/pre-commit
。/../bin/pre-commit
“的符号链接意味着“
一些/path/to/.git/hooks/../bin/pre-commit
,这意味着,通过路径名代数并假设
.git
和/或
.git/hooks
本身不是符号链接,解析为
一些/path/to/bin/pre-commit
,即工作树中的文件
bin/pre-commit
。但是如果您有一个脚本,
。/
是相对于脚本的当前工作目录的,它与脚本的位置无关

幸运的是,
git rev parse
具有一些非常有用的功能,例如:

git rev-parse --show-toplevel
或:

生成顶级工作树和其中的
.git
目录(作为绝对或相对路径,但考虑运行
git rev parse
的进程的当前工作目录)。因此,如果要在工作树中运行
bin/pre-commit
文件:

exec $(git rev-parse --show-toplevel)/bin/pre-commit

我在
.git
所在的目录下运行了
git init
,这应该是正确的方法;但是新的钩子从未进入项目钩子目录——你说的“项目钩子目录”是什么意思?存储库只有一个Git hooks目录,即
.Git/hooks/
git init
不会覆盖此处现有的,但会从模板中添加新的。@torek嗨,对不起,我重新表述了上面的问题。我实际上编辑了一个已经存在的钩子。有没有办法让它用模板钩子覆盖已经存在的钩子?理想情况下,不必删除project.Aha的.git/hooks目录中的钩子。不,Git不会覆盖现有文件,因为它们可能很珍贵:它不知道这些是旧模板,需要用新模板替换。我将添加一个替代方法作为答案(但有一次会很痛苦:-)。
git rev-parse --git-dir
exec $(git rev-parse --show-toplevel)/bin/pre-commit