When I first started learning about dotfiles, one of the recurring topics I kept seeing was 'dotfile management'. There are many 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!
Install Stow
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:
MacOS (Homebrew)
$ brew install stow
Ubuntu (apt)
$ sudo apt-get install stow
CentOS (yum)
$ sudo yum install stow
Archlinux (pacman)
$ 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 an example how my dotfile directory looks:
.
├── alacritty
│ └── .config
│ └── alacritty
| └── alacritty.yml
├── git
│ ├── .gitattributes
│ ├── .gitconfig
│ ├── .gitconfig.local
│ ├── .gitignore
│ └── .stow-local-ignore
├── tmux
│ ├── .tmux
│ ├── .tmux.conf
│ └── js-frontend.yaml
├── nvim
│ └── .config
│ └── nvim
│ ├── .netrwhist
│ ├── Session.vim
│ ├── plugged
│ │ └── ...
│ ├── undodir
│ │ └── ...
│ └── init.vim
└── zsh
├── .zsh
│ ├── environment.zsh
│ ├── history.zsh
│ └── nodejs.zsh
└── .zshrc
Backups + SVC
At this point, we could add git to our directory to handle versioning and backups. I'm an advocate for making your dotfiles public, that way others can observe and learn from your set up. You can also get some inspiration for your own dotfile repo.
Wrapping up
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.
That about sums up how I use stow to manage my dotfiles. You can view my dotfile repo
If you are interested in getting started on your own dotfiles using this same setup, I made a little repo to help you get started: dotfile-starter
I hope this post helped you understand gnu stow and dotfile management a little more.
Cheers!