Using stow to manage dotfiles on multiple systems
As a long time Linux user (almost 25 years now), there are a few tasks which have always been in the back of my mind but which I’ve always neglected. One of them is proper backups. I will come back later to that hopefully (I know). The other is a proper way to manage my dotfiles. I copy my dotfiles between my systems, try to move them to a new system and usually create a new version, trying to invent the wheel all over again every time. I’ve checked GNU stow before, but it did not really click in my mind, or maybe I wasn’t paying attention.
From the examples I saw, I thought the correct way to set up a stow directory was to put configs for different applications in different folders, and than use stow to link to it from your home folder. Like a folder for bash-config, another for bspwm, another for another program, etc. However this did not really made sense too much in my mind because I don’t use the same configuration even if it is the same app on different machines.
After reading for a while, I understand that this is not necessarily the only way to use stow. What I want to do is to have all config files from different “systems”, not different applications, in the same git repository and use stow to manage them.
I guess my use case is a bit different than usual. However I believe I have come to a sensible setup at the end. Here is how to understand the logic behind stow and how I set it up.
Understanding the structure stow expects
Stow expects a directory with subdirectories for each of the configuration groups. I will call this main stow directory “stow repository”. In the repo, each subfolder has config files or folders or whatever else you want to keep, and when you run stow subfolder command, it creates links to the files/folders in the subfolder, and places the links to the parent folder of the stow repo.
- You want to manage the dotfiles in your home directory, so the stow repository should be in your home directory.
- You need subfolders as configuration groups in the stow repo, which has files and folders that you want to manage in them.
| |
Of course, these assumptions work for our use case but stow allows you to manage file linking in much more flexible ways. It is better explained in the links below [2]. However we don’t need to worry about these at the moment just to keep things simple.
My idea for structure
In my case, I want ~/.dotfiles to be my main stow repository with subfolders for each of my machines/systems:
| |
Each system gets their own dotfiles within them:
| |
And it does not have to be only files, it can be whole folders:
| |
So, on a fresh NetBSD installation all I need to do is to install git and stow, clone the repository and stow what I need:
| |
Whatever files that are in netbsd folder is now in my home directory.
Using a common-configs folder to manage common files
For configs that I want to share between different systems, I can place them in common-configs folder, and I can link them in the specific system I want to use this shared config.
| |
My actual setup from zero
I will start with a private repo in Gitlab to manage all files and to track changes in the future. I will go to my Gitlab projects page, New project → Create blank project and create a new project called dotfiles. This will give us a git repo with a single file so we can directly clone to our computer.
| |
We have now our stow repository where we will place our config files which we will be able to track using git. We can just delete the README.md file or put some information and a link to this page in it for future reference.
I will then create folders for each system. I will start with the dotfiles on the Macbook and install stow using brew on MacOS.
| |
A problem we can face at this stage, is that sometimes there are other git repositories in our config folders. If we add a git-tracked folder in another repository, git will give us an error message and tell us that the main repo will not include these folders’ contents when cloned. In my case it is the zsh-autosuggestions repository in ~/.config/zsh/ folder, and I have decided not to include this ~/.config/zsh/ directory in my stow repo and add a note in my README.md to install starship separately (I believe this is how it was installed in the first place).
Other things in my ~/.dotfiles directory
I use keep my scripts and other resources I want to make available on my multiple systems such as a small selection of wallpapers or my customs scripts. I keep them in the same repository but not stow them at all. They are available directly in ~/.dotfiles and ~/.dotfiles/scripts is already added in my $PATH on systems that I want to use these scripts.