Redeploying my FreeBSD desktop last week gave me an excuse to rethink how I save state on machines. The dream would be that local files are backed up, and anything to do with configuration are located in repositories that can easily be cloned elsewhere. This way, I’d take a financial hit by leaving my laptop on a train, or having a motherboard fry itself, but that’s it.

Dotfile repos are a popular way to do this. Browse sites like GitLab, and many people have consolidated their text configuration into one place. I do this too, and symlink essentials into it, such as my kshrc, vimrc, and mpv configs. It’s also fun learning how people use these tools.

I’ve started doing this for private data too, only this time to a local Git repo on my FreeBSD bhyve NAS. From one centralised location I’ve got my KeePassXC password manager vault, Clara’s and my envelope budget spreadsheets, text snippets for Alfred and Kate (sounds like a band), bookmark files, personal Ansible playbooks, and my massive shell script library I’ve amassed over many years.

Just remember if you use Git this way, make the target repository bare or your commits will be rejected. You should also be pushing it to an encrypted drive you trust. On the server:

$ mkdir secret-garden-repo
$ cd secret-garden-repo
$ git init .
$ git config --bool core.bare true

Then on the client, assuming you’re using SSH:

$ git clone server:<PATH>/secret-garden-repo

The only issue right now is handling binary config files that seemingly change with every launch. I suspect they’re writing temporary data or a timestamp each time, which is enough to change the entire file. Certain programs let you specify that you don’t want to compress their data files, which sometimes helps. Otherwise, for those I use a separate folder that I rsync manually instead (though I’m sure there’s a better way).

It’s interesting just how much all this stuff can be shared between OSs thesedays. With a bit of care, my dotfiles and configs work the same on macOS, FreeBSD, NetBSD, and Linux, and my spreadsheets and key files are all using cross-platform tools. My kshrc contains a case `uname` block that lets me define behavior when one specific OS or toolchain deviates from everything else… I’m looking at you, GNU coreutils!