Using GNU Stow to Manage Your Dotfiles

As you know, as an avid console user for many years, you are your dotfiles. My current setup to manage these dotfiles is a combination of combination of Homesick and Git, or specifcally Github.

However, as Homesick itself is a Ruby gems, the dependacy on Ruby was unnecessary heavy and wasteful. After reading Brandon Invergo's experience on using GNU Stow, a symlink farm manager, to manage dotfiles, I was tempted to give it a try. In short, the program itself is more lightweight, portable, and simpler.

First, download the install the program.
$ sudo apt-get install stow

Next, we're going to setup our dotfiles [per-application][8]. Just create the parent folder (dotfiles), the sample package folder (git), and the dotfile we want (.gitconfig).
$ mkdir -p ~/dotfiles/git
$ touch ~/dotfiles/git/.gitconfig

$ tree -a ~/dotfiles/
dotfiles/
└── git
└── .gitconfig

Go to our parent folder (dotfiles) and create the symlink. That's it!
$ cd ~/dotfiles
stow dir is /home/kianmeng/dotfiles
stow dir path relative to target /home/kianmeng is dotfiles
Planning stow of package git...
LINK: .gitconfig => dotfiles/git/.gitconfig
Planning stow of package git... done
Processing tasks...
Processing tasks... done

$ ls -l ~/.gitconfig
lrwxrwxrwx 1 kianmeng kianmeng 23 Mac   8 15:47 /home/kianmeng/.gitconfig -> dotfiles/git/.gitconfig

If the dotfile you're trying to symlink existed, Stow will complain. Let's illustrate this.
$ touch ~/.dummy
$ touch ~/dotfiles/git/.dummy
$ cd ~/dotfiles
$ stow -vv git
stow dir is /home/kianmeng/dotfiles
stow dir path relative to target /home/kianmeng is dotfiles
Planning stow of package git...
CONFLICT when stowing git: existing target is neither a link nor a directory: .dummy
--- Skipping .gitconfig as it already points to dotfiles/git/.gitconfig
Planning stow of package git... done
WARNING! stowing git would cause conflicts:
* existing target is neither a link nor a directory: .dummy
All operations aborted.

To remove the link, just type
$ rm -rf ~/dotfiles/git/.dummy
$ stow -vvD git
stow dir is /home/kianmeng/dotfiles
stow dir path relative to target /home/kianmeng is dotfiles
Planning unstow of package git...
UNLINK: .gitconfig
Planning unstow of package git... done
Processing tasks...
Processing tasks... done

$ ls -l ~/.gitconfig
ls: cannot access /home/kianmeng/.gitconfig: No such file or directory

If you're dotfiles directory is not located under your home direction, for example /home/kianmeng/dotfiles but instead /tmp/dotfiles, you'll need to specify the target path. Otherwise, the symlink will end up in the parent directory, and in this case, /tmp.
$ mv dotfiles /tmp
$ cd /tmp/dotfiles
$ stow -vv -t ~ git
stow dir is /tmp/dotfiles
stow dir path relative to target /home/kianmeng is ../../tmp/dotfiles
Planning stow of package git...
LINK: .gitconfig => ../../tmp/dotfiles/git/.gitconfig
Planning stow of package git... done
Processing tasks...
Processing tasks... done

While GNU Stow is a alternative way of managing dotfiles, unfortunately it still not a good choice to replace Homesick as it lacks of one essential feature, it can't and won't overwrite the existing files! In the end, I ended up another alternative tool, dfm, the dot file manager, written in Perl to manage your dotfiles.

No comments:

Post a Comment