Considering that Git does not recognize symbolic links that point outside of the repository, is there any problem using hard links?
Could Git break them? Can you pl
Google 'git preserve hard links' and it shows that git does not know how to preserve hard link structure AFAIK, perhaps by design.
Web projects of mine use hard links as follows:
www/products/index.php
www/products/dell_latitude_id577/index.php #(hard linked to above)
www/products/dell_inspiron_id323/index.php #(hard linked again to above)
me@server:www/products$ ls -l index.php
-rwxr-xr-x 3 me me 1958 Aug 22 22:10 index.php*
If I wanted to make changes to index.php I change it in one place and the hard links (product detail pages) point to the changes -- except git does not preserve this relationship during cloning and pulling on other computers.
me@server:www$ git pull
on another machine will create a new index.php for each hard link.
The 'tree' object, representing directories in Git, stores file name and (subset of) permissions. It doesn't store inode number (or other kind of file id). Therefore hard links cannot be represented in git, at least not without third party tools such as metastore or git-cache-meta (and I am not sure if it is possible even with those tools).
Git tries to not touch files that it doesn't need to update, but you have to take into account that git doesn't try to preserve hardlinks, so they can be broken by git.
About symbolic links pointing outside repository: git has no problems with them and should preserve contents of symbolic links... but utility of such links is dubious to me, as whether those symlinks would be broken or not depends on the filesystem layout outside git repository, and not under control of git.
From this msysgit issue
Junction points are not symbolic links; therefore, symbolic links are simply unsupported in msysGit.
Also, hard links were never tracked by Git.
The issue were Windows-oriented (since it is about msysgit) and debate about the potential support of symlink.
But the comment about hard link concerns Git in general.
I found out that, using hooks, you can capture the git pull
event (when there is something to pull...) writing the script event handler to .git/hooks/post-merge
file.
First, you have to chmod +x
it.
Then, put the ln
commands inside it to recreate hard links at each pull. Neat huh!
It works, I just needed that for my project and ls -i
shows that files were automatically linked after pull
.
My example of .git/hooks/post-merge
:
#!/bin/sh
ln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdf
ln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdf
ln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdf
ln -f $GIT_DIR/../monografia/monografia_Nilo.pdf $GIT_DIR/../capa/monografia_Nilo.pdf
IMPORTANT: As you can see, the path to any file in your repository should begin with $GIT_DIR
, then add the partial relative path to the file.
Also important: -f
is necessary, because you are recreating the destination file.
Modern git client seems to support symlinks and hardlinks inside of the repository naturally, even when pushing to a remote location and then cloning from it. I never had the need again to link outside a git repo though...
$ mkdir tmp
$ cd tmp
$ git --version
git version 2.24.3 (Apple Git-128)
$ git init .
Initialized empty Git repository in /Users/teixeira/tmp/.git/
$ mkdir x
$ cd x
$ echo 123 > original
$ cat original
123
$ cd ..
$ ln -s x/original symlink
$ cat symlink
123
$ ln x/original hardlink
$ cat hardlink
123
$ git add .
$ git commit -m 'Symlink and hardlink commit'
[master (root-commit) 8df3134] Symlink and hardlink commit
3 files changed, 3 insertions(+)
create mode 100644 hardlink
create mode 120000 symlink
create mode 100644 x/original
$ cd
$ git clone tmp/ teste_tmp
Cloning into 'teste_tmp'...
done.
$ cd teste_tmp/
$ ls
hardlink symlink x
$ cat symlink
123
$ cat hardlink
123
$ cd ~/tmp
$ git remote add origin https://github.com/myUser/myRepo.git
$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 361 bytes | 361.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/myUser/myRepo.git
+ 964dfce...8df3134 master -> master
$ cd ../
$ git clone https://github.com/myUser/myRepo.git
Cloning into 'myRepo'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd myRepo/
$ cat symlink
123
$ cat hardlink
123
https://github.com/mokacoding/symlinks also points an important thing: symlinks must be defined relatively.