threads / discuss / 35747

Having Git follow symlinks

Subject: Having Git follow symlinks

## tl;dr

9 messages between Jan 28, 2014 and Jan 31, 2014.

replies: 8people: 6as markdown or json

Peter Krefting· Jan 28, 2014, 13:49 UTC · lore
Hi!

Is there a (per-repo) setting to get Git to follow symlinks in the working directory, i.e., to not store the symlinks themselves but rather work on what they point to?

Background: I have a repository that stores a number of my dotfiles, 
shared between all my machines (Linux, OSX, Windows/CygWin, Solaris). 
It is currently a CVS repo that I wish to convert to Git since CVS is 
getting more and more scarce. However, I have the repo set up so that 
I check it out into a subdirectory of its own, and have symlinks 
(junctions on Windows) both coming into it (for files that live in ~) 
and out of it (for subdirectories of ~ that cannot be symlinks 
themselves, such as ~/.ssh, or that live elsewhere, such as under 
AppData on Windows or ~/Library on MacOS). CVS handles this by 
simply not knowing anything about symlinks, and I would like to 
get Git to do the same.

I could probably get away with junctions on Windows and directory hardlinks on OSX, but that would not work on Linux.

-- 
\\// Peter - http://www.softwolves.pp.se/
Johan Herland· Jan 28, 2014, 14:47 UTC · re: Peter Krefting · lore

Re: Having Git follow symlinks

On Tue, Jan 28, 2014 at 2:49 PM, Peter Krefting <peter@softwolves.pp.se> wrote:
> Is there a (per-repo) setting to get Git to follow symlinks in the working
> directory, i.e., to not store the symlinks themselves but rather work on
> what they point to?
Not that I know of.
Show 10 quoted lines
> Background: I have a repository that stores a number of my dotfiles, shared
> between all my machines (Linux, OSX, Windows/CygWin, Solaris). It is
> currently a CVS repo that I wish to convert to Git since CVS is getting more
> and more scarce. However, I have the repo set up so that I check it out into
> a subdirectory of its own, and have symlinks (junctions on Windows) both
> coming into it (for files that live in ~) and out of it (for subdirectories
> of ~ that cannot be symlinks themselves, such as ~/.ssh, or that live
> elsewhere, such as under AppData on Windows or ~/Library on MacOS). CVS
> handles this by simply not knowing anything about symlinks, and I would like
> to get Git to do the same.

I believe a preferable way to manage dotfiles in Git, is to have a script that does the necessary setup/installation from the repo (that lives in some subdirectory of ~) and into ~. This script would be able to:

 - Set up whatever symlinks or copies are needed
 - Apply permission/mode bits that are not stored by Git
 - Properly handle various platform differences (symlinks vs. junctions, etc.)

As a bonus, you can run the script as a post-checkout hook, to have it automatically apply any updates you fetch/push into your dotfiles repo.

...Johan
-- 
Johan Herland, <johan@herland.net>
www.herland.net
Peter Krefting· Jan 30, 2014, 09:01 UTC · re: Johan Herland · lore

Re: Having Git follow symlinks

Johan Herland:
> I believe a preferable way to manage dotfiles in Git, is to have a 
> script that does the necessary setup/installation from the repo 
> (that lives in some subdirectory of ~) and into ~.

Yeah, but then I have copies of the files, instead of having the files themselves under version control, meaning I need to copy them back to push changes back, or to merge them. That is undesirable :-/

I do have a setup script for the CVS repo, but it just sets the symlinks up.

The only solution I can see is to split the repo up into several parts, one for each sub-directory that I previously had symlinked. Not perfect, but I guess I can live with that.

-- 
\\// Peter - http://www.softwolves.pp.se/
Christian Couder· Jan 30, 2014, 10:09 UTC · re: Peter Krefting · lore

Re: Having Git follow symlinks

On Thu, Jan 30, 2014 at 10:01 AM, Peter Krefting <peter@softwolves.pp.se> wrote:
Show 5 quoted lines
> Johan Herland:
>
>> I believe a preferable way to manage dotfiles in Git, is to have a script
>> that does the necessary setup/installation from the repo (that lives in some
>> subdirectory of ~) and into ~.

There are tools these days to manage dot files. See for example:

https://github.com/RichiH/vcsh

Best, Christian.

Matthieu Moy· Jan 30, 2014, 12:37 UTC · re: Peter Krefting · lore

Re: Having Git follow symlinks

Peter Krefting <peter@softwolves.pp.se> writes:
> Yeah, but then I have copies of the files, instead of having the files
> themselves under version control, meaning I need to copy them back to
> push changes back, or to merge them. That is undesirable :-/

One option is to have the symlink in the other direction: make /etc/foo a symlink to $GIT_WORKTREE/foo and version the later.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Peter Krefting· Jan 31, 2014, 09:56 UTC · re: Matthieu Moy · lore

Re: Having Git follow symlinks

Matthieu Moy:
> One option is to have the symlink in the other direction: make 
> /etc/foo a symlink to $GIT_WORKTREE/foo and version the later.

I do that for the software that supports it, but ssh, for instance, is very picky that ~/.ssh is a directory and such. And at least one of the other files I version-control will be unlinked and overwritten in such a way that that does not work.

I could split the repo up (that seems to be what "vcsh" is doing) and check the parts out in the corresponding directories, but I do like the idea of having one single repo.

Oh, well, if I have the time, maybe I can come up with a patch. There is already some hacks in the "core.symlinks" setting, so I guess it should be possible.

-- 
\\// Peter - http://www.softwolves.pp.se/
Matthew Ruffalo· Jan 31, 2014, 13:20 UTC · re: Peter Krefting · lore

Re: Having Git follow symlinks

On 01/31/2014 04:56 AM, Peter Krefting wrote:
Show 19 quoted lines
> Matthieu Moy:
>
>> One option is to have the symlink in the other direction: make
>> /etc/foo a symlink to $GIT_WORKTREE/foo and version the later.
>
> I do that for the software that supports it, but ssh, for instance, is
> very picky that ~/.ssh is a directory and such. And at least one of
> the other files I version-control will be unlinked and overwritten in
> such a way that that does not work.
>
> I could split the repo up (that seems to be what "vcsh" is doing) and
> check the parts out in the corresponding directories, but I do like
> the idea of having one single repo.
>
>
> Oh, well, if I have the time, maybe I can come up with a patch. There
> is already some hacks in the "core.symlinks" setting, so I guess it
> should be possible.
>

This is now unrelated to Git, but I have .ssh symlinked to a version-controlled directory on all of my machines (Kubuntu 13.10, 14.04, and recent Gentoo systems, but I've also done this on CentOS 5 and 6).

SSH doesn't care whether ~/.ssh is a symlink, but it *does* //care about permissions:

""" mruffalo@giygas:~$ ls -ld .ssh lrwxrwxrwx 1 mruffalo mruffalo 13 Mar 17 2013 .ssh -> .home-git/ssh mruffalo@giygas:~$ ls -ld .home-git drwx------ 1 mruffalo mruffalo 116 Dec 8 01:26 .home-git """

If .home-git is mode 0755, SSH may refuse to use any private keys that it finds, though I was unable to reproduce this with a few quick tests.

MMR...
Junio C Hamano· Jan 31, 2014, 17:23 UTC · re: Peter Krefting · lore

Re: Having Git follow symlinks

Peter Krefting <peter@softwolves.pp.se> writes:
> ...if I have the time, maybe I can come up with a patch. There is
> already some hacks in the "core.symlinks" setting, so I guess it
> should be possible.

That is totally unrelated. The variable only says "on this platform and/or filesystem, you cannot symlink(2), so instead create a regular file with the symlink contents when checking out a symlink blob". Most importantly, the variable does not change the fact that symbolic links are explicitly tracked without dereferencing.

If you have, under a directory foo/, a symbolic link foo/bar that points at "../baz", a directory foo/baz/, and you have a file at foo/baz/hello:

 1. "git add foo" and "git add foo/bar" will add foo/bar as a
    symlink; and
 2. "git add foo/bar/hello" is an error.

The variable does not have any interactions with the logic to make sure 2. errors out correctly, so the presense of it does not imply anything.

Matthieu Moy· Jan 31, 2014, 17:56 UTC · re: Peter Krefting · lore

Re: Having Git follow symlinks

Peter Krefting <peter@softwolves.pp.se> writes:
> Oh, well, if I have the time, maybe I can come up with a patch. There
> is already some hacks in the "core.symlinks" setting, so I guess it
> should be possible.

I'd love to have a way to follow symlinks, but this needs to be done with care: when following symlinks, writing to a link may mean writing outside the Git repository, which brings some security concerns. Not that following symlinks has to be insecure, but we'd have to make sure that it does not allow a malicious user to e.g. setup a symlink to ~/.bashrc and then write to it.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

← back to recent threads