Managing your dotfiles with stow
Tags: howtos, linux, osx, software
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:
- Cross-platform support (we are using OS X at work, while Arch Linux is still going strong on my personal devices)
- Light-weight
- 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:
-
Create a dotfiles
git
repository. You want this because you can usegit
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 thatgit
is also a version control system? You definitely want this! -
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. -
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, sincevim
, 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. -
To activate a configuration, you go into your dotfiles repository, and issue
stow vim
, for example. This makes Stow look for all files in thevim/
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!