Our team has a set of dotfiles at thoughtbot/dotfiles. They contain vim, git, zsh, and tmux configuration that many of us use every day.
Each of us also have personal sets of dotfiles. They augment our team dotfiles with configuration such as aliases for our personal workflow, our name and email for git, and vim syntax highlighting for languages such as Go, Scala, Haskell, or Clojure that we’re playing with but that we typically don’t use on client projects.
We recently released rcm which, among other things, allows a workflow where those two sets of dotfiles co-exist in harmony.
Team dotfiles as primary
The team’s dotfiles could be considered the primary dotfiles repo. It is well-vetted and we can depend on it matching the latest conventions and practices agreed upon by our team.
mkdir thoughtbot
cd thoughtbot
git clone https://github.com/thoughtbot/dotfiles.git
Note the directory convention is to keep local git repos matching the
{user,organization}/project
GitHub structure, which also matches a Go
convention.
Once we have our team dotfiles cloned, we should install rcm. On OS X, we can use the Brewfile:
brew bundle dotfiles/Brewfile
See the docs to install on other platforms.
Next, we use rcm’s rcup
command to symlink files from thoughtbot/dotfiles to
~/.aliases
, ~/.gitconfig
, ~/.psqlrc
, ~/.tmux.conf
, ~/.vimrc
,
~/.zshrc
, and others:
rcup -d dotfiles -x README.md -x LICENSE -x Brewfile
The -x
options, which exclude the README.md
, LICENSE
, and Brewfile
files, are needed during installation but can be skipped during future rcup
updates because we are symlinking the ~/.rcrc
file during installation, which
knows to exclude those files.
If we reload our shell at this point, we’d now have all the great features from thoughtbot/dotfiles available to us. The most obvious immediate change would be the look of our prompt.
Personal dotfiles as secondary
Now, we need our personal dotfiles, for example croaky/dotfiles:
mkdir croaky
cd croaky
git clone https://github.com/croaky/dotfiles.git
rcup -d dotfiles -x README.md
That’s it! Our two sets of dotfiles are living in harmony. But how does it work?
The .local
convention
At the end of the files we symlinked from thoughtbot/dotfiles are lines such as
this in ~/.zshrc
:
# Local config
[[ -f ~/.zshrc.local ]] && source ~/.zshrc.local
Or this in ~/.vimrc
:
" Local config
if filereadable($HOME . "/.vimrc.local")
source ~/.vimrc.local
endif
These lines say “now, look for a file of the same name as myself, but with an
extra .local
extension.” This convention makes it clean to have a second set
of dotfiles around without one trampling on the other.
Most of the files we have in personal dotfiles end in .local
. They are
additive to the team dotfiles, which is why it can help to think of the
personal dotfiles as “secondary.”
Overwrite
In some cases, the .local
convention isn’t available, so we need to
completely overwrite the file.
For example, if we use the fail-fast
option in our personal rspec
config but it is not popular amongst the team, it is inappropriate to
live in the team dotfiles, which should represent only a reasonable subset that
is valuable for everyone.
In that example, when we next update team dotfiles, rcm asks if we want to overwrite the file:
rcup -d dotfiles
overwrite /Users/croaky/.rspec? [ynaq] n
This demonstrates how rcm lets us pick a winner, and prefer our personal preference in this case.
What’s next
We recommend creating and evolving a set of team dotfiles. We can each learn many workflow tips from our teammates in team dotfiles pull requests.
With rcm’s ability to manage both team and personal dotfiles together, there’s no reason to be afraid of using team dotfiles, because we can always override the decisions in our personal set.