Dotfile Management

I switch machines i work on often, and its important to me that my configuration is up-to-date on all of them.

I needed a solution which would address the following topics:

  • dotfiles should be backed up in one place which will be the source of truth
  • i should be able to easily make changes to this source of truth from any machine
  • all my machines should be able to easily sync with this source of truth

In short, I should be able to use one machine for days, make config changes on it, and then when i move to another machine, all of my config changes should be applied to the other machine as well.

To accomplish this, I found a pretty nice solution using a Bare Git RepositoryBare Git Repository
A bare GitGit
Git is a version control system used to track changes on files and make it easier for multiple people to collaborate on the same set of files.

This note serves as a link to connect Git-related not...
repository is a repository without a working tree. If you create a bare repository, you'll get just the contents that you'd normally find within .git directory.

Since it doesn't hav...
.

Initial setup

Lets create a new GitGit
Git is a version control system used to track changes on files and make it easier for multiple people to collaborate on the same set of files.

This note serves as a link to connect Git-related not...
repo to store our config:


git init --bare $HOME/.cfg

To control the repo neatly with a dedicated command, we can create a config alias like so:


# make sure to save it to wherever you keep your aliases, e.g. `.zshrc`
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'

Notice that even though repository is in .cfg, the work tree is your home directory. This allows us to add any files in your home directory to this repository. Test the alias and set up the repository by configuring it to only track the files we've explicitly added:


# instead of git config
config config --local status.showUntrackedFiles no

The last step is to add your config files and push them:


config add .zshrc
config add .config/nvim/init.vim
# ...
# add anything else you are using
# ...
config commit -m 'add initial configuration'
config push


Setup once repo exists

Every other time you are setting up (e.g. on a new machine), your repository will already exist, so the procedure is somewhat different:


git clone --bare $YOUR_GIT_REPO $HOME/.cfg

# make sure to save it to wherever you keep your aliases, e.g. `.zshrc`
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'


Now that config command is ready and repo is cloned, you can execute config checkout to get your config files.

There might be trouble with conflicts if you already have some config files on your machine. Its best you back them up and then do a reconciliation to see if what you currently have needs to go into your main configuration.

A neat script to automatically back up your current files if they are conflicting:


BACKUP_DIR="~/.config-backup"

if config checkout; then  
	echo "No conflicts, checkout succesful.";  
else  
	echo "Backing up pre-existing config files to $BACKUP_DIR";  
	mkdir $BACKUP_DIR 
	config checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | xargs -I{} mv {} $BACKUP_DIR/{}  
	echo "Repeating checkout now that pre-existing files are moved."
	config checkout
fi



The only thing left to do now is to disable showing untracked files (just like we did before), and reconcile your conflicting configuration. Make the changes to your main files based on what you have in your .config-backup directory, execute a config add / config commit / config push of the changes (if any) and you are good to go!

Just dont forget to do config pull on your other machines to sync back your changes.


Status: #🌲

References:

Part of Git RunbooksGit Runbooks
This note serves as a collection of [[Git]]-related how-to guides that lead you through the steps of solving real-world problems. To use it, follow the linked mentions below.