Managing your dotfiles with git

A few months ago Lord published an interesting article on dotfiles management with git. It motivated me to make my own clean setup, which I will talk about here.

As I'm amongst to the worst compulsive tinkerers, let's forget the usual symlink mess and enjoy the tools provided by versioning software, which are all very useful in this particular case.

We'll start right off. Lord did something I loved: binding all of git's garbage in a separate folder. I'd really disappointed by all those hundreds of hidden folders lying outside of .config, needless to say this is a mandatory feature for me. A few parameters do the trick, so we need to create an alias in .bashrc:

## git hacks
# binds garbage to ~/.gitdot (for dotfiles management)
alias gitdot="git --git-dir=/home/cylgom/.gitdot --work-tree=/home/cylgom"

Each change in our repo will make use of gitdot. Don't forget to source your .bashrc so you can use the alias:

source ~/.bashrc

Now, create a new repo and add the configuration files you need with the gitdot command:

gitdot init
gitdot add ~/.bashrc
gitdot add .vimrc
gitdot commit -m 'initial commit'

Then, push the repo where neededn and you can easily clone your dotfiles in another /home. Or can you ?

rm -rf .gitdot
gitdot clone https://github.com/cylgom/dotfiles.git ~

Actually, git should insult you shamelessly saying the folder is not empty. This might be a useful mechanism for developpement, but there is no way to turn it off! I must confess this is the main reason this guide exists, because in his article Lord simply suggests moving the content of your /home so you can clone - not very handy. However, cheating is definitely possible, and that's exactly what we are going to do:

gitdot init
gitdot remote add origin https://github.com/cylgom/dotfiles.git
gitdot fetch
gitdot checkout -f -t origin/master

Nothing fancy, we just initialize an empty repo and add the adress of the first one in the remotes list. This way, we can pull the commits and fake a clone in a dirty folder, but we also keep the file tracking and all the power of git to help us manage them.

To further explain the checkout command, the 't' option sets the "upstream" configuration for the new branch, and the 'f' option forces the branch switch even if the working tree differs from HEAD.

Now all we need is a bash script to do this for us. the resulting file can be hosted in a gist or at the root of your website. We must keep in mind that on another computer, our gitdot alias won't exist, so it needs a few changes :

#!/bin/bash
gitdot="git --git-dir=/home/cylgom/.gitdot --work-tree=/home/cylgom"
eval $gitdot init
eval $gitdot remote add origin https://github.com/cylgom/dotfiles.git
eval $gitdot fetch
eval $gitdot checkout -f -t origin/master
source ~/.bashrc

Et voilĂ  ! Everything should work fine.