Managing your dotfiles with stow

Tags: howtos, linux, osx, software

Published on
« Previous post: A Mathematician’s Utility — Next post: Towards Topological Machine Learning »

I was recently graciously issued another laptop at work, bringing up the total number of machines I regularly use to three. This finally prompted me to update my workflow for managing my dotfiles, i.e. those pesky little files that contain all kinds of configuration options and start filling up your home directory. Previously, I rolled my own solution based on a Lua script, but I did not want to maintain it any longer and was actively looking for something that has the following features:

  1. Cross-platform support (we are using OS X at work, while Arch Linux is still going strong on my personal devices)
  2. Light-weight
  3. Simple git integration

After reviewing some of the existing options and quizzing Max, I came across GNU Stow. Being a Perl script, it certainly is cross-platform and light-weight; and it turns out that it integrates surprisingly well with git. The use case of Stow is actually something related, viz. providing an easy way to create symbolic links for software that you only installed locally. Here is how I use it to manage my dotfiles:

  1. Create a dotfiles git repository. You want this because you can use git branches for managing different machines or different operating systems. Also, git gives you synchronization options, which is great when you quickly want to roll out your changes to another systems. Moreover, did I mention that git is also a version control system? You definitely want this!

  2. Clone your repository into $HOME/.dotfiles. That way, it is out of the way for most operations but since it is a subdirectory of $HOME, the paths generated by Stow will work as expected. More about this later.

  3. For every program that you want to manage, create a separate subdirectory in the dotfiles repository. Inside this subdirectory, create as many directories as needed in order to replicate the file location relative to $HOME. For example, since vim, the best editor in the world, uses $HOME/.vim/spell to store its spellchecker files, you would place the configuration in $HOME/.dotfiles/vim/.vim/spell. This might look strange at first glance, so just think of the dotfiles repository reflecting all paths relative to your home directory.

  4. To activate a configuration, you go into your dotfiles repository, and issue stow vim, for example. This makes Stow look for all files in the vim/ subfolder; each of them will be propagated to your home directory. Of course, Stow will not overwrite any file that already exist there, so after making a backup of them, you can safely delete them and make Stow do the rest.

As you can see, this is a really simple setup: Stow will create symbolic links to the files that belong to a package, i.e. that are part of the same folder. That is all there is to do here—I really find this to be an amazingly simple and easy setup. Here are some additional tricks that might be useful:

  • Your dotfiles repository can contain a “bootstrap” script for setting up a new machine. This script could detect the operating system, install some packages, and issue some initial stow commands for you.

  • As briefly alluded to above, you can use branches in your dotfiles repository to support different machines or operating systems if necessary. I am not doing this at the moment yet because my configuration is platform-independent, at least for the time being. But thanks to git and its merging capabilities, separate branches could be maintained relatively easily.

  • Stow is purposefully simple when it comes to package names, so you could also create package names depending on the operating system, or something similar. Bear in mind, though, that it is a good idea to keep your repository simple—many dependencies are not a good way of making you want to use and rely on this.

I have not yet found a minimalistic way to push all configurations to other systems, though. This is likely to be a more major undertaking and so for now, I am truly content in the knowledge that my git, vim, and python configurations (among others) can be easily synchronized.

Good filing, until next time!