#stow #dotfiles #bash
My dotfile management and versioning was mediocre at best. I had a dotfiles git repository where each branch represents a different machine. However, making sure that I captured all my changes in git was challenging since there wasn’t a link to from the dot file to my dotfile repo. GNU Stow to the rescue!
What is GNU Stow?
GNU Stow manages sym links. That’s all it does. It consolidates all the original files in a singe location, but separated by packages. Each package, or directory, contains the same directory structure as the location the original file is located.
e.g.
The following file:
xmonad/.xmonad/lib/Xmonad/Util/Brightness.hs
will be
stowed in the target directory at
.xmonad/lib/Xmonad/Util/Brightness.hs
.
Typically the target directory is the parent of the package
directory, but his can be changed via the -t
option.
You can “stow” the config to the target directory by executing
stow xmonad
, and delete it by
stow -D xmonad
. However, I like being explicit in my
commands. There are some default options that I explicitly use.
e.g. stow xmonad
would be the same as
stow -St ~ xmonad
.
Migrating to Stow
I had my dotfiles directory in my home directory that is versioned using git.
~/dotfiles
I originally had a flat directory structure where all dotfiles
resided in this main directory. To start using stow, I had to create
sub directories for each stow package
. The result is the
following:
~/dotfiles$ tree -d
.
├── bash
├── git
├── local
├── sbt
├── vim
└── xmonad
Migrating to this setup was pretty easy. I created the package directory, mimicking the directory structure of the target file(s) I want to stow, along with empty files with the same name as the target.
e.g.
cd ~/dotfiles
mkdir -p xmonad/.xmonad/lib/Xmonad/Util/
touch Brightness.hs
Then, I used the --adopt
flag to move the files from
my home directory to the package directory, then create the symbolic
link using stow
. Before doing any real modifications, I
always used the --no
flag to just do a trial run of
executing the command along with the -v
flag for a more
verbose output.
e.g.
To test the command:
stow --adopt --no -vSt ~ xmonad
To finally execute the command.
stow --adopt -vSt ~ xmonad
I repeated the process for all my dotfiles using different packages them into different packages.
Here’s the final result for the xmonad
package.
~/dotfiles$ find xmonad -type f
xmonad/.xmonad/lib/XMonad/Util/Brightness.hs
xmonad/.xmonad/xmobar.hs
xmonad/.xmonad/xmonad-session-rc
xmonad/.xmonad/xmonad.hs
~/dotfiles$ cd
~$ find .xmonad -type l -ls
26345986 4 lrwxrwxrwx 1 freddie freddie 65 Sep 6 14:06 .xmonad/lib/XMonad/Util/Brightness.hs -> ../../../../dotfiles/xmonad/.xmonad/lib/XMonad/Util/Brightness.hs
24117849 0 lrwxrwxrwx 1 freddie freddie 36 Sep 6 14:06 .xmonad/xmobar.hs -> ../dotfiles/xmonad/.xmonad/xmobar.hs
24117857 0 lrwxrwxrwx 1 freddie freddie 44 Sep 6 14:06 .xmonad/xmonad-session-rc -> ../dotfiles/xmonad/.xmonad/xmonad-session-rc
24117860 0 lrwxrwxrwx 1 freddie freddie 36 Sep 6 14:06 .xmonad/xmonad.hs -> ../dotfiles/xmonad/.xmonad/xmonad.hs
2020-Oct-04