The biggest productivity boost I’ve gotten is from creating my own dotfiles repo. Increasingly, I am doing software development inside ephemeral environments. At Amazon, we used a mix of EC2 and our local machines but largely stuck to 2-3 environments. At GitHub, I am primarily using Codespaces, but even outside of work, I am using devcontainers for geneac.

I used to believe that the best way to work was to find a set of tools that had a sensible set of defaults and learn to use them without reconfiguring them. I’ve been using bash and vim for years for that reason, because you can be pretty sure that any system you use will have at least those.

What changed? In this case, I started using VS Code exclusively, and it will automatically clone your dotfiles repo for you in every new environment! This allows me to have all the tools I need set up just in time to start writing some code. If it’s not automatic, it most cases I can just clone the repo and run the installer script, which is a two-line job:

$ git clone git@github.com:mrysav/dotfiles.git ~/.dotfiles
$ bash ~/.dotfiles/install.sh

The Files

The GitHub dotfiles site has recommendations on tools and techniques for writing dotfiles, in addition to some example repos. Naturally, I ignored those and made my own. That’s not strictly necessary, but a lot of the fancy repositories you see are optimized to that person’s specific workflow, and mine is still pretty spartan.

Include over Copy/Paste

One thing you’ll notice in my repo is that I add files as “includes” rather than completely replacing the existing files. I do this because there are platform defaults that I want to respect - for instance, I do a lot of work in Ubuntu machines, and there is a default .bashrc that each user gets, and I’m fine with it. I just want to add my stuff on top of it. This also has the advantage of being able to edit the file in the repository directly. I could have the same experience with symlinks, but, see above.

Optional component installers

I tried for a while to make rbenv and nodenv automatically install without any issues on all/most environments, but I was not successful. Instead, I opted to make a helper script to invoke “installers” in my dotfile directory so I can install it with one command on environments where I need it.

My .bashrc already includes the file to initialize rbenv if it’s present, so if I need it, I can just run dfi install rbenv, restart the shell, and be on my way.

Work in Progress

The nice thing is that I’ve made making changes super easy. dotfiles is an alias to change the current directory to wherever the repo is cloned, and then I can make the change with vim, git add, git push and that’s it.

I’m trying to get into a offlineimap + neomutt setup for email that I would expect to be able to put here. I’ve also been an occasional user of ncmpcpp and mopidy for a while, although I don’t have any specific configuration.

One thing to watch out for is to make sure you don’t commit any application secrets to the repo. I’ve gotten around that by machine-specific .secrets.env files, but that’s kind of messy and not very convenient, so I need to think some more there.