summaryrefslogtreecommitdiff
path: root/content/gnu_stow.md
blob: 33ebb731cc7391a276ce999d8ed8ba803611ec32 (plain)
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
---
date: 2022-06-09T19:10:00+02:00
draft: fale
type: productivity
title: Managing dotfiles with 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.
<!--more-->
Let's take a very typical dotfiles repository.

```
./nvim/init.lua
./tmux/tmux.conf
```

You want to have those files available as 

```
~/.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

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.

```
~/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 sylink as


```
~/target/config/one.conf
~/target/config/two.conf
~/target/config/three.conf
```

Let's stow the first one

```
cd ~/target/stow
stow one
```

And see what happened

```
cd ~/target
ls -lA
```

We get somethine like

```
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

```
cd ~/target/stow
stow two
```

and what we get

```
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.

```
cd config
ls -lA
```

```
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 sub trees for "one" and
"two"m and joined then 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 struture of the actual config! Coming back
to our example, we can have a 

```
~/dotfiles/tmux/.tmux.conf
~/dotfiles/nvim/.config/nvim/init.lua
```

Then, after stowing both packages we have symlinks under our desired


```
~/.config/nvim/init.lua
~/.tmux.conf
```

GNU Stow is a very simple tool. All we understand what will happen with each sub tree.