Git and hard links Git and hard links git git

Git and hard links


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.


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/shln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdfln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdfln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdfln -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.

EDIT

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 --versiongit 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 original123$ cd ..$ ln -s x/original symlink$ cat symlink123$ ln x/original hardlink$ cat hardlink123$ 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

Cloning from local git repository

$ cd$ git clone tmp/ teste_tmpCloning into 'teste_tmp'...done.$ cd teste_tmp/$ lshardlink  symlink  x$ cat symlink123$ cat hardlink123

Cloning from remote repository

$ cd ~/tmp$ git remote add origin https://github.com/myUser/myRepo.git$ git push origin masterEnumerating objects: 5, done.Counting objects: 100% (5/5), done.Delta compression using up to 8 threadsCompressing 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.gitCloning 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 0Unpacking objects: 100% (5/5), done.$ cd myRepo/$ cat symlink123$ cat hardlink123

https://github.com/mokacoding/symlinks also points an important thing: symlinks must be defined relatively.


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.