在 git 中指向钩子的符号链接

我编写了自己的自定义合并后钩子,现在我添加了一个“钩子”目录到我的主项目文件夹(因为 git 不跟踪变化。Git/hooks) ,在某个地方我读到,我可以创建一个从 hooks 到。Git/hooks,这样我就不必每次有人更改文件时都把它从一个文件夹复制到另一个文件夹,所以我尝试了:

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

但好像不管用,知道为什么吗?“挂钩/合并后”。Git/hooks/post-merge”工作得很好,但是创建一个硬链接和复制是一样的,我想... ..。

30980 次浏览

you just used wrong path, it should be:

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

Changing directory before linking

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

why not just cp ./hooks/* .git/hooks/

this worked for me in Mac OS

The path calculation is done relative to the symlink. Let's understand using an example,

ln -s path/to/file symlink/file

Here, the path to the file should actually be the relative path from the symlink path.
The system actually calculates the file path as symlink/path/path/to/file
The above command should be re-written as

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

The folder structure being,

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

While you can use symbolic links, you can also change the hooks folder for your project in your git settings with :

git config core.hooksPath hooks/

Which is local by default so it won't ruin git hooks for your other projects. It works for all hook in this repository, so it's especially useful if you have more than one hook.

If you already have custom hooks in .git/hooks/ that you do not want to share with your team you can add them in hooks/ and add a .gitignore so they're not shared.

Utilizing Michael Cihar's comment, here is an example of a bash script I wrote to simply create these symlinks. This script is located in git_hooks/ dir which is at the project root. My .git/ folder is also in the same directory level.

#!/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

My script must be ran from within the actual git_hooks/ directory. You can modify it to behave differently, if you'd like.

This script will symlink any file that is not suffixed with a file extension within the git_hooks/ directory. I have a README.txt in this directory + this script (named symlink.sh). All the actual git hooks are named 'pre-commit', 'pre-push', etc. so they will be symlinked.