Git tracking dotfiles (example: .zshrc)

On my mac at the root I have my .bashrc, .aliases, .zshrc..., then in another folder down the way I have a git repository of the same dotfiles. When I update the ones at the root, I update the git repo as well (manually). Is there some way to 'link' the dot files that are actually implemented at the root folder to the git repo so I only have to deal with one change?

Upvotes: 3

Views: 784

Answers (3)

Petr Skocik
Petr Skocik

Reputation: 60097

You can actually 'link' those files with ln. You can use either symbolic links (-s) or hard links. If you use a UNIX (like system) you should learn about links.

Symbolic links are essential special files that contain a path (relative or absolute) and are treated by the system as if they're the file on that path (this means that symbolic links can become broken).

Hard links (created by ln without the -s flag) are limited to a single filesystem and a hardlink is just a name for the same chunk of bytes as the original file. Hardlinks are indistinguishable from the original file. In fact a file is just a hardlink (=name for an inode) with count 1. (The second column in the listing of ls -l shows you the number of hardlinks (names) that exist on the filesystem for a given file.)

I've also put my dotfiles in a repo. In my repo. I have the dotfiles in a directory named payload and my repo also contains a script that links the dotfiles in payload to my home directory.

The script is as follows:

    #!/bin/bash
    shopt -s dotglob #make globbing catch dotfiles too
    #Use -f (force) to overwrite targets
    for file in payload/*; do ln -s .${PWD/$HOME/}/$file $HOME/; done #use string substitution

Edit I found that a simpler way to get the relative path in the link is to use the -r option to ln:

    for file in payload/*; do ln -s -r $file $HOME/; done 

You can also create multiple links at once by using the 3rd form of ln (see man ln):

    ln -s -r payload/* $HOME/

For a hardlink version, you could do:

 #!/bin/bash
 shopt -s dotglob #make globbing catch dotfiles too
 ln payload/* $HOME/ 

(This hardlink version won't get broken with moves and renames, but your repo must be on the same filesystem)

(All this assumes that you've only got files (not directories) in payload/ and that your links should have the same name as their targets.)

There are more sophisticated programs that do this in a more robust fashion.

Upvotes: 4

redShadow
redShadow

Reputation: 6777

I usually use symbolic links for this, eg:

mkdir ~/.dotfiles
mv ~/.zshrc ~/.dotfiles
ln -s ~/.dotfiles/.zshrc ~/.zshrc
cd ~/.dotfiles ; git init ; ...etc...

..so that the file that actually gets opened is the one under version control in your ~/.dotfiles directory.

Another option is use application-specific "include" features, eg:

  • put your "standard" configuration in ~/.dotfiles/.zshrc
  • source that file from ~/.zshrc:

    [ -e ~/.dotfiles/.zshrc ] && . ~/.dotfiles/.zshrc
    

Upvotes: 4

ThanksForAllTheFish
ThanksForAllTheFish

Reputation: 7251

What about symbolic link?

Just delete the file in your root, and recreate them as

ln -s /physical/path/to/file /symbolic/link/path

For example, if you have the file /git/.aliases, ln -s /git/.aliases /root/.aliases will create a symbolic link called .aliases in the root folder. From this point on, whichever file you modify (/git or /root) will modify the other one as well.

Have a look at this link for more details on symbolic links and Mac.

Please, forgive me for the random paths, I am not a Mac users.

Upvotes: 5

Related Questions