Dotfile Management with Elegance

In my previous post, I touched upon the purpose of dotfiles and the recommended specifications governing their creation. For those of us who spend countless hours customizing and perfecting dotfiles, an elegant approach for dotfile management can be well worth the investment. Having such an approach not only enables us to port our configurations to different systems but lets us do so with ease.

Let us look at a typical use case scenario. You have a primary machine on which you spend most of your time. Over time, you have perfected the configuration of various programs to your liking. Now you deploy a server in the cloud and start typing various commands to do simple tasks or configure program preferences all over again. Does it not make sense to just port all your configurations and settings to the new server? You could copy the required dotfiles to the server either through SFTP, SCP or some other way or use version control and create a repository for all your dotfiles. Now they can follow you wherever you want. In addition, you also get the benefits of versioning all your changes and reverting if needed. Once you clone the repository on the target machine, it is a simple job of creating symlinks or copying/moving the requisite files to the home directory.

The workflow for this method would be:

mkdir -p ~/dotfiles/bash
cd ~/dotfiles/bash
git init
cp ~/.bashrc .
git add bash/
git commit -m "My first commit with my bashrc”

You can add all the dotfiles and directories that you wish to version control by copying them to this directory and committing your changes. Presuming that you have pushed your changes to your remote and cloned the repository on the target machine, it is now a simple matter of creating symlinks to the required dotfiles.

cd ~
ln -s ~/dotfiles/.bashrc .bashrc

A ls -la will show you the symbolic link and the file it points to in your repository. While the above method is effective, it is not efficient. You might have a few tens or even hundreds of these dotfiles and directories. The symlink creation task is too cumbersome and prone to errors. So, is there a better way?

GNU Stow for Dotfile Management

GNU Stow is a symlink farm manager. It allows users to manage multiple versions of the same software. We can also use it for dotfile management in the user’s home directory.

The usage is simple. We have already organized our dotfiles in different subdirectories within the dotfiles directory in our home folder. We have also version controlled it. To use GNU Stow, all we need to do is to issue the command gnu stow for which we want to create symlinks in the home directory. Remember that GNU Stow will create the symlinks in the directory one level up from where you execute the command. Continuing the above example, we could use stow to handle the symlink creation for us.

cd dotfiles
stow bash

A point to note here is that if a file goes in the top level of your home directory, it would go in the top level of the program’s subdirectory. If a file goes in the default $XDG_CONFIG_HOME/$PKGNAMElocation, Ex: $HOME/.config/$PKGNAME, then it would go in $HOME/dotfiles/$PKGNAME/.config/$PKGNAME.  Check out Brandon’s article on GNU stow for Dotfile Management for a complete example.

Git Bare for Dotfile Management

You can also use just git to manage your dotfiles. That includes version controlling your dotfiles and porting them to any machine you desire and setting them up. There is a good article by Nicola Paolucci on Atlassian denoting this method. It is a good method for those who want to use pure git to achieve the desired results or for git buffs, however; I am not really a fan of this method. In brief, you can create a bare git repository and directly track files in place, your home folder, by adding them to the bare repo.

The problem with this method is that when you restore your files on a different machine, you will have the entire shebang even if you don’t need them. Yes, you can do a sparse checkout and get only those files that you need. However, the organization of the repo is not as logically structured as in the above case and the solution can soon become unwieldy if you have too many dotfiles floating around.

In conclusion, you can choose any of the above methods for your dotfile management. My favorite is GNU Stow as it makes dotfile management a breeze as compared to the other methods.