yochem.nl

Bare Dotfiles Repository: how to do "sparse checkouts"

⚠️ This post is still work-in-progress.

One of the most elegant approaches to managing “dotfiles” (configuration files for CLIs) is by using a bare git repository, to my knowledge first introduced by Nicola Paolucci on the Atlassian website. You should definitely read the short tutorial if you haven’t, but it basically advices you to create a bare repository and a shell alias to reference that repository:

$ git clone --bare <repo_url> ~/Documents/dotfiles
$ alias dot='git --git-dir="$HOME/Documents/dotfiles" --work-tree="$XDG_CONFIG_HOME"'

Or for fish:

function dot
  git --git-dir="$HOME/Documents/dotfiles" \
    --work-tree="$XDG_CONFIG_HOME" $argv
end

Note: I’ve adapted the alias slightly to work just for $XDG_CONFIG_HOME (usually ~/.config) as I like to keep my $HOME clean 1.

After the bare clone, no code is checked out yet. That means the work tree (our config folder) is not touched yet. If we would continue the examples from the blog post, we would checkout the main branch with dot checkout which would possibly fail with the message that files could be overwritten.

To solve this problem, I recommend to create a new orphan branch and manually checking out the configs you need on this specific machine. For example, to only use my Neovim config on this machine:

$ dot switch --orphan $(hostname)
$ dot restore -s main -- nvim

The --orphan flag is optional, but it prevents that the first commit to the new branch is a “I deleted almost everything except these configs” commit.

Bonus: Ignore Local Config

You might have noticed that I don’t set showUntrackedFiles to false. This is by design. I don’t want to forget to track config files of new CLIs. If I really want to ignore them, I add them to Git’s local ignore file $GIT_DIR/info/exclude. Here’s a Git alias I use for it:

$ config config alias.exclude "!echo "${1?no argument}" >> $(git rev-parse --git-path info/exclude) && :"
$ config exclude htop

  1. See my post on config files in $HOME ↩︎