Dotfile Management With GNU Stow
By Jon Leopard on 16 January 2017
When I first started learning about dotfiles, one of the recurring topics I kept seeing was 'dotfile management'. There are a plethora of ways of solving this issue. I decided to keep things simple and use GNU Stow.
A brief description of stow from the project site:
GNU Stow is a symlink farm manager which takes distinct packages of software and/or data located in separate directories on the filesystem, and makes them appear to be installed in the same place. For example, /usr/local/bin could contain symlinks to files within /usr/local/stow/emacs/bin, /usr/local/stow/perl/bin etc.,
Apart from simplicity, I picked stow because its friendly to almost every *nix environment, and doesn't require extra dependencies to be installed. I can easily keep a version controlled directory of my dotfiles.
Although stow is great for this use case, it's capabilities far extend the scope of this guide, we'll learn just some of the basics of what stow has to offer. So lets get started!
Stow is available for all linux and unix like distros via your package manager. Here are a couple ways to install it, choose which one applies to you:
$ brew install stow
$ sudo apt-get install stow
$ sudo yum install stow
$ sudo pacman -S stow
Confirm that it installed:
$ stow --version stow (GNU Stow) version 2.2.2
Create a test directory
Now that stow is installed, lets create a test directory with some dummy files:
$ cd && mkdir -p test/foo/ && mkdir test/bar/ && touch test/foo/.foo && touch test/bar/.bar
You'll now have have a folder named "test" in your home directory with two folders nested inside(foo, and bar). Each of those two folders contains a dummy file(.foo, and .bar). The command will also put you inside the /test folder once it is finished.
Here's how that directory structure looks (pre-stow)
. ├── bar │ └── .bar └── foo └── .foo
By default, stow will create symlinks for files/folders in the parent directory of where you execute the command. Lets now create our first symlink!
$ stow foo
Now go up a directory and ls -al to see what happened:
cd ../ && ls -al total 8 drwxr-xr-x 4 jon staff 136 Jan 15 20:31 . drwx------+ 38 jon staff 1292 Jan 15 19:37 .. lrwxr-xr-x 1 jon staff 13 Jan 15 20:30 .foo -> test/foo/.foo drwxr-xr-x 4 jon staff 136 Jan 15 20:27 test
You should now see a symlink pointing to the original file in the directory.
Lets run the same command on our older folder, bar. You'll need to run stow on each of the files/folders you wish to create symlinks for.
$ stow bar
Here's another way of viewing the directory:
. ├── .bar -> test/bar/.bar ├── .foo -> test/foo/.foo └── test ├── bar │ └── .bar └── foo └── .foo
Here's how my dotfile directory looks:
. ├── git │ ├── .gitattributes │ ├── .gitconfig │ ├── .gitconfig.local │ ├── .gitignore │ └── .stow-local-ignore ├── tmux │ ├── .tmux │ │ ├── .tmux.conf │ │ └── .tmux.conf.local │ ├── .tmux.conf │ ├── .tmux.conf.local │ └── .tmuxp │ ├── 4pane.yaml │ └── js-frontend.yaml ├── nvim │ └── .config │ └── nvim │ ├── .DS_Store │ ├── .netrwhist │ ├── autoload │ │ └── plug.vim │ ├── config │ │ ├── color.vimrc │ │ ├── general.vimrc │ │ ├── init.vimrc │ │ ├── keys.vimrc │ │ ├── line.vimrc │ │ └── plugins.vimrc │ └── init.vim └── zsh ├── .zsh │ ├── environment.zsh │ ├── history.zsh │ └── nodejs.zsh └── .zshrc
I'm working on making my vim directory a little less complex. Instead of having hundreds of lines of code in my .vimrc, I decided to modularise them for organisational purposes.
Backups + SVC
At this point, we could add git to our directory to handle versioning and backups. Im an advocate for making your dotfiles public, that way others can observe and learn from your set up. Check out some awesome dotfile repos here: https://dotfiles.github.io/
I haven't quite mastered the art of dotfile management, but stow has certainly helped me get one step closer. In the future, I would like to make my dotfiles portable enough so that, with the help of some bash scripting, my environment could be pulled from my repo and set up in any linux environment via ssh.
That about sums up how I use stow to manage my dotfiles. You can view my dotfile repo here: https://github.com/jonleopard/dotfiles
I'm still working on the installation scripts and documentation, (in fact, I could use some help making those scripts since I'm still a n00b) so be cautious if you are going to duplicate anything of mine.
I hope this post helped you understand stow and dotfile management a little more.