Everyone is managing their dotfiles these days. A search on GitHub for “dotfiles” will provide a lot of results.
There are many tools designed to make the process simple, and I have tried a few. Mackup, for instance is a neat little solution that symlinks a selection of dotfiles to your dropbox. Yet Another Dotfile Manager is another (which, as far as I can tell, is essentially a wrapper around git).
However, I have been seduced by GNU Stow. While not explicitly intended for dotfile management, a lot of people have used it as such. I liked the slightly more manual aspect of the solution—it felt rather as if I would have more control over what was backed up and what was not.
Let’s start at the beginning.
The why
If you run ls -a on your home directory, you will be confronted by a host of hidden files and folders. If you use Vim
for instance, you will find a .vimrc file and probably a .vim folder as well. The .vimrc file will contain settings that modify the behaviour of Vim. You may not use Vim, but you will certainly find some files there for something you do use, such as .bashrc, or .zshrc.
If you have customised these files at all, you will certainly want to back them up. In the event that you move to a new machine, for whatever reason, you don’t want to be reconstructing them from scratch, from memory.
It is tempting to think that git has the solution to this problem. After all, not only can you have a record of all the changes made to each file (at least, from the inception of the git repository), but you can also mirror the repository elsewhere, such as at GitHub. But, if you initialise a repository in your home directory, you are going to have a pretty hard time managing your .gitignore file, which will be changing all the time.
So, you may think, why not move all the configuration files to a single folder, and initialise a git repository there? Well it solves our first problem, but now Vim, say, will not know where to look for the .vimrc file. Perhaps you can tell Vim to look in your new location, perhaps you cant. But even if you can tell all the programs about all the new locations, do you really want to be left managing that process manually? What happens when you update a plugin?
The what
To get around both problems, you can do the following: Move all the relevant files to a new folder. Then symlink them back into the home folder so all the programs will continue to work as if nothing has changed. Initialise a git repository in the new dotfiles location, push it to github and you are safe.
This still requires manually moving and symlinking all the files you want, but that is where GNU Stow comes in.
Stow is a symlink manager, and makes the process extremely fast indeed.
The how
Make sure Stow is installed. Use your package manager—I use a Mac so I use Homebrew.
brew install stow
I’m making a place for my dotfiles in my home directory, but you can put it wherever you like.
mkdir ~/dotfiles
cd ~/dotfiles
git init
Now it’s time to move some dotfiles to our new location. I’m going to start with Neovim and my .zshrc file. The reason being that .zshrc lives in the home folder ~ while Neovim places it’s config inside ~/.config/nvim. Frankly, if only all programs did this we would be better off, but alas. Starting with .zshrc:
mv ~/.zshrc ~/dotfiles/zsh
This moves .zshrc to ~/dotfiles/zsh. Now for Neovim.
mv ~/.config/nvim/init.vim ~/dotfiles/neovim/.config/nvim
Notice the difference here. When we ask stow to symlink zsh, it will put a symlink at ~ to all the files in the zsh folder. But that would be no good to Neovim, which expects to find it’s dotfiles in .config/nvim. To account for this, we put the file inside two folders named so as to mirror the expected path.
Now to generate the symlinks.
cd dotfiles
stow zsh
stow neovim
Now if we ls -a in our home directory, we should see a symlink to .zshrc. If we cd into .config/nvim, we should see a symlink to init.vim. If we start Neovim, it should work exactly as before.
Pitfalls
There is something to be aware of when doing this however. It’s to do with the nature of git.
It’s possible that you might think about putting your .vim folder in your dotfiles repository. After all, why not keep all of your Vim configuration together? But be careful - you may end up moving a folder containing another git repository inside your dotfiles repository, and Git does not like this very much.
It’s probably possible, but for now, I’m going to play it safe.