Personal Programming Notes

To err is human; to debug, divine.

Let’s say we have folders with many symbolic links in them, linking to other files in the same Git repository.

Unfortunately after committing into Git, they’ve turned into plain text files. Note that even after committing and pushing into Git, the symlinks still work fine. However, after some branch switches and code merges, the symlinks become actual text files with the link target as the contents.

Before going into lengthy discussion on how Git handles symlinks and hard links, the quick solution for the above problem is the following Bash script:

where ls -d1 $folder/* should be replaced with some command that will list exactly the files you want, preferably in full path. Note that -f option of ln command is required to replace the file with the symlink. For examples: Best practice note: I think that the following template is preferred to the more commonly seen for f in$(ls *); do...done:

I think it is the better way to handle all file names, especially with spaces, since "$f" will still work. In addition, $(cmd) is the same as 'cmd' (backticks) but it can be nested, unlike using backticks. It fact, it’s the main reason why the backticks have been deprecated from Bash scripting.

How Git deals with symlinks is defined in the git config core.symlinks. If false, symbolic links are checked out as small plain files that contain the link text. Otherwise, Git just stores the contents of the link (i.e., the path of the file system) in a ‘blob’ just like it would for a normal file. It also stores the name, mode and type (e.g., symlink) in the tree object that represents its containing directory. When you checkout a tree containing the link, it restores the object as a symlink.

After the symlinks are checked out as plain text files, I believe it is pretty much no way for Git to restore symlinks again (i.e., follow symlinks inside text files). It would be an insecure, undefined behavior: what if the symlink as text file is modified? What if the target is changed when moving between versions of that text file?

One of the disadvantages is that the file will be created as a normal file during git checkout, because there is no way Git understand it as a link. Moreover, hard link itself has many limitations, compared to symlinks, such as files have to reside on the same file-system or partition. In Mac OSX, hard links to directories are not supported. There is a tool to do that, but use it with caution.