Managing Dotfiles Using a Git Bare Repository

Author: Jake Bauer | Published: 2020-06-13

I’ve recently overhauled a lot of the software I use which means I have a whole new set of configuration files for most of that software. I figured it would be a good time to change the way I manage these configuration files too. I’ve started fresh with a new repository for my dotfiles and retired my old repository.

I used to manage my dotfiles by manually copying files to and from the git repository folder or with symlinks but found this far too cumbersome to manage. I recently read about managing dotfiles with a bare repository and switched to doing it that way.

This is what’s required to set it up:

git init --bare $HOME/docs/proj/dotfiles
alias config='git --git-dir=$HOME/docs/proj/dotfiles --work-tree=$HOME'
config config --local status.showUntrackedFiles no

And this is what needs to be done on a new machine to deploy my dotfiles:

git clone --bare $HOME/docs/proj/dotfiles
rm ~/.bashrc ~/.profile
alias config='git --git-dir=$HOME/docs/proj/dotfiles --work-tree=$HOME'
config checkout
config config --local status.showUntrackedFiles no
config update-index --skip-worktree LICENSE .gitignore
rm LICENSE .gitignore

I opted for this method over using another application like chezmoi or GNU Stow because I didn’t want Yet Another Bit of Software to manage what could be done by just using git. I also didn’t want to make my entire home folder a git repository because I’ve heard that it can cause problems when you have nested repositories that aren’t part of the same project, of which I have many.

You’ll notice a .gitignore,, and LICENSE file in that repository. Normally, that would mean I’d have to have those files in my home directory but, by using the --skip-worktree feature, I can write, add, commit, and then delete those files without git caring. For example, I would write the file, then do:

$ config add
$ config commit -m "Add README"
$ rm
$ config update-index --skip-worktree

If I need to update any of those files, I can do something like:

$ config update-index --no-skip-worktree
$ config checkout --

then edit, add, commit, delete, and re-ignore that file.

Now, all of my configuration files are in my home directory and there is no copying involved. If I update something on one machine and push those changes, I can easily apply those changes to another machine. Deploying dotfiles to a brand new system is a little more of an involved process, but it can be easily scripted and it doesn’t happen that often anyways.

This is my forty-fourth post for the #100DaysToOffload challenge. You can learn more about this challenge over at