git钩子的符号链接


86

我编写了自己的自定义合并后钩子,现在我在主项目文件夹中添加了一个“ hooks”目录(因为git无法跟踪.git / hooks中的更改),因此我读到可以从钩子建立符号链接的地方到.git / hooks,这样我就不必在每次有人更改文件时都将文件从一个文件夹复制到另一个文件夹,因此我尝试了:

ln -s -f hooks/post-merge .git/hooks/post-merge

但这似乎不起作用,有什么主意吗?“在钩子/合并后.git / hooks /合并后”效果很好,但进行硬链接与我想的copyin相同...


22
因为符号链接是相对于其位置解析的。其中的符号链接.git/hooks/指向hooks/post-merge解析为.git/hooks/hooks/post-merge,不存在。你要ln -s -f ../../hooks/post-merge .git/hooks/post-merge。或让您的生活更轻松:ln -s -f ../hooks .git/hooks。您的问题与git无关。
亚里斯多德·帕加尔兹


如果我错了,请纠正我,但是仍然必须为每个工作站设置一个Symlink。唯一保存的是手动复制它,或编写另一个将跟踪的钩子文件复制到的命令.git/hooks
adi518

Answers:


161

您刚刚使用了错误的路径,应该是:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge

10
我不明白为什么我需要向上两个目录来链接位于我已cd进入的文件夹中的资源。难道不是ln -s ./hooks/吗?
Droogans

45
这个。当git评估符号链接时,它显然是将.git/hooks其用作工作目录,因此相对路径应相对于该目录。如果您在进行符号链接之前先cd进入.git/hooks,并弄清楚从那里开始的相对路径,这将更加不言自明。
艾略特2014年

12
@Eliot创建或解析符号链接都不受工作目录的影响。您提供的任何内容ln都将存储为目标,并相对于链接的位置进行解析。
JOO亚当

2
@JoóÁdám你是对的。因此,这里的问题是原始命令指定了错误的相对路径。不过,在创建链接之前请cd仔细阅读.git/hooks该文档,因为它随后可以自动完成至正确的路径。
艾略特

1
最后,所有这些对我都起作用。唯一的区别是我链接到自己的链接prepare-commit-msg。问题是,如果我使用nano编辑提交消息,然后Ctl + X退出,则git仍会完成提交,而不是像我进行此更改之前那样放弃。有没有办法在不导致此提交完成的情况下退出nano?
frakman1年7

15

虽然可以使用符号链接,但也可以使用以下命令在git设置中更改项目的hooks文件夹:

git config core.hooksPath hooks/

默认情况下是本地的,因此不会破坏其他项目的git hooks。它适用于此存储库中的所有钩子,因此如果您有多个钩子,则特别有用。

如果您已经有了自定义的钩子,.git/hooks/并且不想与您的团队共享,则可以将它们添加到hooks /中,然后添加一个,.gitignore这样它们就不会被共享。


非常好!一个方便的技巧:)似乎比将它们一个一链接起来更能适应未来的需求。
jkp

2

链接前更改目录

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge

在之后更简单cdln -s -f ../../hooks/post-merge
jamesdlin

0

路径计算是相对于符号链接完成的。我们来看一个例子,

ln -s path/to/file symlink/file

在这里,文件的路径实际上应该是符号链接路径的相对路径。
系统实际将文件路径计算为symlink/path/path/to/file
:上面的命令应重写为

ln -s ../path/to/file symlink/path


/ code
------ symlink / file
------ path / to / file


0

利用Michael Cihar的评论,这是我编写的bash脚本示例,用于简单地创建这些符号链接。该脚本位于项目根目录下的git_hooks /目录中。我的.git /文件夹也位于同一目录级别。

#!/usr/bin/env bash

pwd=$(pwd);

# Script is designed to be ran from git_hooks/ dir
if [[ "$pwd" == *"git_hooks"* ]]; then

  files=$(ls | grep -v -e '.*\.');

   while read -r file; do

     ln -s ../../git_hooks/$file ../.git/hooks/
     echo "Linked $file -> ../.git/hooks/$file"

   done <<< "$files";

else

  echo "";
  echo "ERROR: ";
  echo "You must be within the git_hooks/ dir to run this command";
  exit 1;

fi

我的脚本必须从实际的git_hooks /目录中运行。您可以根据需要将其修改为不同的行为。

此脚本将符号链接git_hooks /目录中未带有文件扩展名的任何文件。我在此目录+此脚本(名为symlink.sh)中具有README.txt。所有实际的git钩子都被命名为'pre-commit','pre-push'等,因此它们将被符号链接。


-1

为什么不只是cp ./hooks/* .git / hooks /

这在Mac OS中对我有用


15
因为I don't have to copy the file from one folder to the other every time someone changes
George Dimitriadis
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.