1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
+++
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.
|