This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the unix category.
Last Updated: 2024-11-23
A repo contained the folder ./githooks
. I wanted to symbolically link the
pre-commit
file here to .git/hooks
in order to get my git hook to run (while
also being in version control)
I ran the following from .
$ ln -s githooks/pre-commit .git/hooks/pre-commit
It ran without an error exit code, but then the hook did not work:
$ ./.git/hooks/pre-commit
zsh: no such file or directory: ./.git/hooks/pre-commit
Inspecting the symbolic link with ls -l
showed:
$ ls -l .git/hooks/pre-commit
lrwxr-xr-x 1 jack staff 19 Dec 30 13:07 .git/hooks/pre-commit -> githooks/pre-commit
This seems OK, but watch what happens if I cd
out of the current codebase and
into the parent folder before running ls -l
again
cd ..
ls -l child/.git/hooks/pre-commit
lrwxr-xr-x 1 jack staff 19 Dec 30 13:07 child/.git/hooks/pre-commit -> githooks/pre-commit
Notice how the symlink is pointing to the same directory as before - i.e. it was not updated to be aware of my working directory.
The key here is that the symlink needs to be given a relative path to where it's going relative to its position. Thus the command, back up in the root directory of my project, would have been
$ ln -s ../../githooks/pre-commit .git/hooks/pre-commit
# i.e. tell the OS how to get from .git/hooks to githooks
This is difficult to remember so a best practice is to use absolute paths instead
ln -s $(pwd)/githooks/pre-commit .git/hooks/pre-commit
Another easy way to prevent this confusion would to always cd
into the directory where
the symlink will live before running the linking command. Now autocomplete will
help you figure out the correct relative path.
Use absolute paths with ln -s