If you’re like me you find yourself moving between multiple systems. Whether that be between my personal desktop and my work laptop or distro hopping on Linux. See relevant meme below:

Distro Hopping Meme

What are dotfiles?

Many tools/program store their configuration files as files on your machine. On Linux you will often find these in ~/.config directory.

Some common examples of dotfiles:

- .vimrc
- .bashrc
- .gitconfig

I wanted to find an easy way to manage my dotfiles and share them between mutiple systems. I also wanted a easy way to install software/tools I used between my systems. Introducing DotBot, a tool that provides an easy way to manage our dotfiles using VCS (git).

How does it work?

Dotbot works by creating symlinks between files in your git repo to a location on your filesystem i.e ~/dotfiles/bashrc -> ~/.bashrc. So this means if we edit either file it will edit in both places. Typically I will edit the files in the dotfiles repo. You can then commit and push your changes at your leisure.

Symlinks A symlink or a Symbolic Link is basically a shortcut to another file. It is a file that points to another file.

Why manage dotfiles with git?

One of the main reasons to use VCS (git) to manage your dotfiles is very much the same reason you would use VCS normally. It allows us to track the history of files, so we can see all the changes made to it. Recently in my case I have been trying different shells. I prefer to keep my dotfiles clean so when I stop using a shell I delete it. For example I swapped from zsh back to fish. I moved from zsh to fish shell, and deleted my ZSH config. If I ever need my zsh config back I can trawl through my git history and retrieve it.

Getting started

To get started with a brand new repository we can use the init-dotfiles script.

curl -fsSLO https://raw.githubusercontent.com/Vaelatern/init-dotfiles/master/init_dotfiles.sh
chmod +x ./init_dotfiles.sh
./init_dotfiles.sh

# Output

Welcome to the configuration generator for Dotbot
Please be aware that if you have a complicated setup, you may need more customization than this script offers.

At any time, press ^C to quit. No changes will be made until you confirm.

~/.dotfiles is not in use.
Where do you want your dotfiles repository to be? (~/.dotfiles)
Shall we add Dotbot as a submodule (a good idea)? (Y/n) y
Will do.
Do you want Dotbot to clean ~/ of broken links added by Dotbot? (recommended) (Y/n) y
I will ask Dotbot to clean.
I found ~/.profile, do you want to Dotbot it? (Y/n) y
Dotbotted!
I found ~/.bashrc, do you want to Dotbot it? (Y/n) y
Dotbotted!
Shall I make the initial commit? (Y/n) y
Will do.

This will create an empty dotfiles repo we can then configure, it will look like:

.
|-- bashrc
|-- dotbot
|-- install
|-- install.conf.yaml
`-- profile

install.conf.yaml

The main config file install.conf.yaml is where we configure what files to copy and where to copy them.

The default version of this file will look something like this:

- clean: ['~']

- link:
    ~/.profile: profile
    ~/.bashrc: bashrc

Let’s break down what this file is doing;

clean

Clean commands specify directories that should be checked for dead symbolic links. These dead links are removed automatically. Only dead links that point to somewhere within the dotfiles directory are removed unless the force option is set to true - Dotbot

So this means it will check our home directory (~) for any dead symbolic links and remove them.

This is the main part of config file, it tells DotBot where to symlink the files in our dotfiles repo on our systems. For example, the profile file in the dotfiles repository will be copied to ~/.profile location.

~/.profile: profile

If you want to copy all the files in a folder you could so something like:

- link:
    ~/.config/fish:
      path: fish/**
      glob: true
      create: true

We will copy everything from the fish folder in the dotfiles repo to the ~/.config/fish location.

  • path: acts as a glob and will copy everything in this folder to the location we specified
  • glob: if set to true will treat path as a glob
  • create: if set to true will create the folders for us if they don’t exist, for example ~/.config/fish folder

shell

We can also add a shell field where you specify commands to run on the shell. If we want to install starship prompt we could do something like this.

- shell:
    - command: curl -fsSL https://starship.rs/install.sh | sh -s -- --yes
      stdout: true
      stderr: true

We set stdout and stderr to true so we can see the command output.

How to run it?

To “install” our dotfiles on our machine run the following command ./install. This wil run all the commands in order of the config file we defined above.

Closing Thoughts

Now that we have a repo locally, we can push it to a remote git repository like Github or Gitlab. That way if we lose access to our machine we still have our dotfiles backed up and safe.

Dotfiles Meme

Appendix