Managing your dotfiles

Here is how I manage my dotfiles, host them on GitHub, and store my secrets.

Dotfiles repository

Firstly, you'll want to have a repository to store all your dotfiles, which should not include any secrets / personal data. I'll get to that later.

For example, you might include:

  • .bashrc
  • init.vim
  • VsCode's settings.json

Basically anything that you want to keep once you get a new device and install the system again. Or, things that you want to keep shared between multiple devices at the same time.

To create the repository:

mkdir dotfiles
cd dotfiles
git init

Now, there are two ways of managing dotfiles. Either by creating a bare repository and cloning it directly to your home directory and using an alias to call git to make changes later, or by using symbolic links.

I personally used the bare repository method previously and found it quite tedious to make changes to it, so I would recommend you stick to symlinking.

Let's say you want to share your .bashrc, so you move it to ~/dotfiles/.bashrc. All you need to do now is add a symbolic link to it by utilizing ln:

ln -sv ~/dotfiles/.bashrc ~

(-v is used for verbose logging, in case it fails to link).

After creating the link, you can edit ~/.bashrc, but it will in fact edit the file in dotfiles, same goes for reading.

So wait, are we going to have to manually create a link to all the dotfiles?

Using GNU Stow

GNU Stow is an utility for managing your symlinks. It allows you to easily link and split them into modules, so you can decide which parts you'd like to link.

It should be available in your distro, for example on Arch (yes, I use arch) all you need is sudo pacman -S stow.

Now what? You could use the dotfiles directory as one big module, or split them into submodules, such as dotfiles/bash.

Linking a module requires a single command:

cd ~
stow -t ~ dotfiles

And if you'd rather use modules instead:

cd ~/dotfiles
stow -t ~ bash
stow -t ~ neovim
stow -t ~ fonts

Here is an example of my dotfiles that use GNU stow.


After switching to Gnome 3.36 (which is awesome btw) from BSPWM, I realised that it doesn't have an easy way of managing it's configuration between devices.

However, after a quick Google search it turns out that you can dump all your config using this command:

dconf dump / > dconf.conf

And to restore it:

dconf load / < dconf.conf


VsCode actually happens to have a great extension which saves your config to a gist and synchronises it between devices. However, I like to keep my configuration consistent whenever possible and have everything in one place.

So, you'll need to symlink the settings.json and keybindings.json in .config/Code - OSS/User. You'll also need to dump the list of installed extensions with the following command:

code --list-extensions > .code-extensions

and to restore it:

cat .code-extensions | xargs -L 1 code --install-extension

Keeping your secrets

Let's say you would like to sync your ssh keys in case your device gets lost, or simply in case you are moving to a new device.

You might be thinking, hey I'll just store it in a private Git repo. What could possibly go wrong.

Please don't.

Many 3rd party GitHub integrations ask for private repo access, and you can't blacklist a single repo. For example, if you want to deploy a static blog in a private repo to Netlify, you'll have to give private repo access.

Even if Netlify isn't going to steal your secrets, it increases a chance of a 3rd party that exploits a Netlify vulnerability and accesses your stuff through them.

So, here is how you could store them instead:

However, you'll need to use a GPG key, which could get relatively complex, would make it insecure if you fail to store it correctly, and could lead to losing the data in case you don't back it up properly.

So, you will probably want to store your ssh private key in a reliable password manager service and/or print out a QR code of it.

Dominik Tarnowski
I write code.