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:

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.

Tags: