Managing Dotfiles With GNU Stow
GNU Stow
GNU Stow manages symlinks, or symbolic links. Stow can make packages, collections of files and directories, appeared installed in a target directory. The stow directory is the root of a tree containing packages in its sub-trees.
Stow can be used to install any tree of files, including a software package like
Emacs, with its binaries and libraries sub-directories. I use Stow to manage
configuration (“dotfiles”) and other user-specific files in my $HOME
directory.
Usage
stow [options] [action flag] package ...
Relevant Options:
--target=dir
-t dir
By default, the target directory is the parent of the stow directory. My target is $HOME but I might not want to keep my stow directory there.
--dotfiles
Tells Stow to preprocess files and directories prefixed with ‘dot-’ by replacing the prefix with a period. This lets me do what I need without having a directory full of hidden files.
--delete
-D
Deletes or unstows the specified packages, i.e., the packages following the option from the target directory.
--restow
-R
Unstows and then stows again the specified packages. Useful for pruning obsolete symlinks.
--stow
-S
Explicitly stows the specified packages. Useful when performing multiple
operations like -R
in the same invocation.
Example
Consider the following tree.
$HOME/
├─ my_stow_dir/
│ ├─ my_first_pkg/
│ │ ├─ Documents/
│ │ │ ├─ diary.txt
│ ├─ my_second_pkg/
│ │ ├─ .hidden.txt
Where my_stow_dir
is the stow directory, $HOME
is the target, and
my_first_pkg
and my_second_pkg
are packages.
Invoking Stow to stow both packages will create a symlink diary.txt
in
Documents/
, a directory already present in my $HOME
, and .hidden.txt
.
We can see that every package’s sub-tree will be “written” to the target directory.
For Dotfiles
Lately, I find myself wanting my dotfiles across:
- a couple of laptops running GNU/Linux or macOS
- the odd headless server or Raspberry Pi
- containers for my development workflows
I use software like Bash across all my devices, while something like Sway is only relevant for my GNU/Linux machines with a display. What seems like a reasonable setup to me, is to create packages based on use cases. For example, my configs for Sway, Waybar, and Foot are all a part of my graphical needs. Dotfiles for Git, text editors, and some CLI tools are part of my development needs. With this setup, I don’t have to install a package for every program I need or a single package with all my dotfiles, just a package that will cover my needs on a specific type of device.