Why?

(I think) I've got a pretty nice setup for my terminal. I'm using zsh (shell) with oh my zsh (configuration framework) and powerlevel10k (theme). I have both a personal and a work computer, and I'd like to minimize the amount of work needed to keep the configuration for those in sync.

Previously I would upload gists of the most important configuration files and then use them wherever they were needed. That was cumbersome and I often forgot to update them after making minor changes on one computer.

I currently have a setup where I can use a git repository to keep track of the changes, and a specific alias that makes it easier to work with.

How?

I have all the configuration files in a repository on GitHub, which I've cloned into a local folder. By using symlinks I can let the files in that folder control the configuration of my computer.

To simplify things, I have an alias setup that makes it easy to work with these configuration files no matter where I'm currently at.

My inspiration was this post and this one. I like the thought of using an alias in the first post, but the use of a "bare" git repo was new to me and doesn't feel as flexible. The second post shows the same kind of solution that I have: symlinks from where the file should be, to where it actually is.

Dotfiles

So the dotfiles I'm talking about are basically all of the configuration files that makes my terminal work and look the way I want it to. Examples of these kind of files are .gitconfig and .zshrc, but it could be any configuration file that you'd like to have setup the same way on multiple computers.

Setup the repository

The first thing we have to do is create a repo on GitHub called dotfiles (or whatever you like). Clone that repo to a local folder, for example ~/dotfiles, and we're ready to go.

Setup the alias

This step isn't strictly neccessary, but I found it to be a nice touch. The idea is that in whatever path I'm currently at, I can always do something lika config status to see if I have any pending changes to my config files.

Without this step, I would have to do all config management related work while being in the actual git repo.

So what we're doing here is setting up config which basically just is an alias for git but with a hard coded working directory (the dotfiles repo).

# Setup the alias locally, so you don't need to restart the terminal when setting this up
alias config='/usr/bin/git --git-dir=$HOME/dotfiles/.git --work-tree=$HOME/dotfiles'
# Save the alias to your `.zshrc` so it's persisted across restarts
echo "alias config='/usr/bin/git --git-dir=$HOME/dotfiles/.git --work-tree=$HOME/dotfiles'" >> $HOME/.zshrc`

Symlink and start versioning a file

Move the file from it's original location to the dotfiles git repo. Then create a symlink from the original location to the new location:

mv $HOME/.zshrc $HOME/dotfiles/.zshrc
ln -nfs /Users/$USER/dotfiles/.zshrc /Users/$USER/.zshrc

Now all we need to do is to add the file to git to get it under version control:

config status
config add .zshrc
config commit -m "Added .zshrc"
config push

Make changes to a file

As you make changes to your dotfiles, all you need to do is to push these changes to remote repository, so that you can update them on your other computer.

config status
config add .zshrc
config commit -m "Updated .zshrc
config push

On another computer

The process on you other computer will be much the same:

  1. Clone the repo
  2. Setup the alias
  3. Remove the original dotfiles and replace them with symlinks to the files in the repo