Symbolic link to a hook in git

LinuxGitGithooks

Linux Problem Overview


I wrote my own custom post-merge hook, now I added a "hooks" directory to my main project folder (since git doesn't track changes in .git/hooks), somewhere I read that I can make a symbolic link from hooks to .git/hooks so I don't have to copy the file from one folder to the other every time someone changes it so I tried:

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

But it doesn't seem to work, any ideas why? "ln hooks/post-merge .git/hooks/post-merge" works fine but making a hard link is the same as copyin I guess....

Linux Solutions


Solution 1 - Linux

you just used wrong path, it should be:

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

Solution 2 - Linux

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.

Solution 3 - Linux

Changing directory before linking

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

Solution 4 - Linux

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

Solution 5 - Linux

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.

Solution 6 - Linux

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

this worked for me in Mac OS

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMateusz DymczykView Question on Stackoverflow
Solution 1 - LinuxMichal ČihařView Answer on Stackoverflow
Solution 2 - LinuxPierre.SassoulasView Answer on Stackoverflow
Solution 3 - LinuxJekisView Answer on Stackoverflow
Solution 4 - LinuxswayamrainaView Answer on Stackoverflow
Solution 5 - Linuxcchoe1View Answer on Stackoverflow
Solution 6 - LinuxFrazkoView Answer on Stackoverflow