+++ title = "GNU Stow" author = ["MichaƂ Sapka"] date = 2022-06-09T22:26:00+02:00 categories = ["blog", "update"] draft = false weight = 3002 abstract = "GNU Stow is a tool for managing symlink farms, used primarily for dotfiles. Here you can find a short guide on how to use it." aliases = ["/articles/gnu-stow"] +++ If you are working with Linux/BSD based system, you are most likely accustomed to managing your configs with dotfiles. And you most likely have them stored with Git. But there is the never ending problem of how to actually use them. I have moved management of this under GNU Stow. Let's take a very typical dotfiles repository. ```shell ./nvim/init.lua ./tmux/tmux.conf ``` You want to have those files available as ```shell ~/.config/nvim/init.lua ~/.tmux.conf ``` The most popular approach would be to symlink the files under the expected location. We could also copy the files every time something changes, but that would be crazy. Are we the stuck with having to do those symlinks manually every time we install a new machine or create a virtual one? And what if we have dozens of such configs stored under git? ## Symlink farm {#symlink-farm} GNU Stow is a symlink farm. This means, that it's a system aimed at automating creating of those symlinks. [GNU Stow website](https://www.gnu.org/software/stow/manual/stow.html) For Stow, the dotfiles directory is called "Stowed" directory. Now comes the cool part. Each folder in the Stowed directory (called "Package directory") stores a separate directory tree. GNU Stow will join all those separate trees and create a proper structure under Target Directory, which by default is the parent of Stowed directory. Let's look at example. ```shell ~/target/stow/one/config/one.conf ~/target/stow/two/config/two.conf ~/target/stow/three/config/three.conf ``` So, our home director now has a "Target" directory, which has a "Stow" directory. The Stow directory stores three configs which we want to symlink as ```shell ~/target/config/one.conf ~/target/config/two.conf ~/target/config/three.conf ``` Let's stow the first one ```shell cd ~/target/stow stow one ``` And see what happened ```shell cd ~/target ls -lA ``` We get something like ```shell lrwxrwxrwx 1 msapka wheel 15 Jun 9 23:01 config -> stow/one/config drwxr-xr-x 5 msapka wheel 4096 Jun 9 22:55 stow ``` Stow created a config symlink in the target directory. Very cool, but it gets cooler! Let' stow the second one ```shell cd ~/target/stow stow two ``` and what we get ```shell drwxr-xr-x 2 msapka wheel 4096 Jun 9 23:03 config drwxr-xr-x 5 msapka wheel 4096 Jun 9 22:55 stow ``` Our config is no longer a symlink, but a real folder. Let's see what's inside here. ```shell cd config ls -lA ``` ```shell lrwxrwxrwx 1 msapka wheel 27 Jun 9 23:03 one.conf -> ../stow/two/config/one.conf lrwxrwxrwx 1 msapka wheel 26 Jun 9 23:03 two.conf -> ../stow/one/config/two.conf ``` We have our two configs, but what has happened? Stow looked at both subtrees for "one" and "two" and joined them in a way, that is possible. The only way for one.conf and two.conf to exist in config is if config is a normal directory. Extremely cool! Let's image that our target is actually homedir, so we have a ~/dotfiles directory. Then each package directory can mimic the tree structure of the actual config! Coming back to our example, we can have a ```shell ~/dotfiles/tmux/.tmux.conf ~/dotfiles/nvim/.config/nvim/init.lua ``` Then, after stowing both packages we have symlinks under our desired ```shell ~/.config/nvim/init.lua ~/.tmux.conf ``` GNU Stow is a very simple tool. All we need to understand what will happen with each subtree.