Managing dotfiles with GNU Stow and git
If you regularly use the command-line in *nix systems, you probably are familiar with dotfiles. Dotfiles are hidden files that store user-defined configuration for different applications, generally the text-based ones. In other words, dotfiles define the personalized environment that a user feels comfortable working with. Examples of these personalization aspects include command aliases, keyboard shortcuts etc. (as a shameless plug, you can check mine on GitHub to get an idea).
When moving these dotfiles from one computer to another, the user can have the same environment across different machines, without having to worry about different system settings.
The nature of these files make them perfect to use them with version control systems: just checkout or clone the repository and you have a working familiar setup in seconds. Moreover, if you make them public, people can check them and see if they suit their workflow and adopt them. GitHub, for instance, keeps a curated list of nice dotfiles.
Most dotfiles reside on the root of the home directory of the user (
/home/username). However, having a version control repository in the home directory can be messy, as every subdirectory would inherit the context of the version controlled home root directory (longer explanation here). This is where GNU Stow comes in.
Dotfiles with GNU Stow
According to its official page, 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.
Basically, it creates symbolic links (symlinks) of files in places where the original files are supposed to be, so the original files can be stored elsewhere for easier handling. As most GNU projects, its documentation is available online in different formats.
Let’s assume we have the following directory structure with dotfiles, where all the dotfiles by default reside on the home directory (bad idea with version control)
home |- .bashrc |- .bash_profile |- .vimrc |- .tmux.conf |- dev |- Music . .
Now we move the dotfiles to a different directory, such as
~/dotfiles, and we classify the dotfiles with according to different programs:
home |- dotfiles | |- bash | | |- .bashrc | | |- .bash_profile | |- vim | | |- .vimrc | |- tmux | | |- .tmux.conf |- dev |- Music . .
We change to the dotfiles directory and run stow:
$ cd dotfiles $ stow bash $ stow vim $ stow tmux
Each time we run Stow, it creates a symlink in the parent directory for each of the files that are stored in the dotfile subdirectory. For instance, when running stow bash, it will create symlinks for .bashrc and .bash_profile.
By default, stow will create the symlinks in the parent directory. If the desired target for the symlinks is not the parent directory, we run stow with the -t option. For example:
$ stow -t ~ vim
Therefore, we just clone the git repository in a directory of our choice, and with stow, we can just create symlinks in the proper directory. Better, we get to choose which dotfiles we want to symlink (for instance, we don’t need GUI related symbolic links in remote servers).
This way, we have a comfortable, fast and safe way of managing our dotfiles, without using custom scripts. If you prefer an example, you can check my dotfiles on GitHub to see in practice how managing dotfiles with GNU Stow and git makes a really good choice. Feel free to clone or fork the repository.