Managing my dotfiles as a git repository December 30, 2019 on Drew DeVault's blog

There are many tools for managing your dotfiles - user-specific configuration files. GNU stow is an example. I’ve tried a few solutions over the years, but I settled on a very simple system several years ago which has served me very well in the time since: my $HOME is a git repository. This repository, in fact. This isn’t an original idea, but I’m not sure where I first heard it from either, and I’ve extended upon it somewhat since.

The key to making this work well is my one-byte .gitignore file:

*

With this line, and git will ignore all of the files in my $HOME directory, so I needn’t worry about leaving personal files, music, videos, other git repositories, and so on, in my public dotfiles repo. But, in order to track anything at all, we need to override the gitignore file on a case-by-case basis with git add -f, or --force. To add my vimrc, I used the following command:

git add -f .vimrc

Then I can commit and push normally, and .vimrc is tracked by git. The gitignore file does not apply to any files which are already being tracked by git, so any future changes to my vimrc show up in git status, git diff, etc, and can be easilly committed with git commit -a, or added to the staging area normally with git add — using -f is no longer necessary. Setting up a new machine is quite easy. After the installation, I run the following commands:

cd ~
git init
git remote add origin git@git.sr.ht:~sircmpwn/dotfiles
git fetch
git checkout -f master

A quick log-out and back in and I feel right at $HOME. Additionally, I have configured $HOME as a prefix, so that ~/bin is full of binaries, ~/lib has libraries, and so on; though I continue to use ~/.config rather than ~/etc. I put $HOME/bin ahead of anything else in my path, which allows me to shadow system programs with wrapper scripts as necessary. For example, ~/bin/xdg-open is as follows:

#!/bin/sh
case "${1%%:*}" in
	http|https|*.pdf)
		exec qutebrowser "$1"
		;;
	mailto)
		exec aerc "$1"
		;;
	*)
		exec /usr/bin/xdg-open "$@"
		;;
esac

Replacing the needlessly annoying-to-customize xdg-open with one that just does what I want, falling back to /usr/bin/xdg-open if necessary. Many other non-shadowed scripts and programs are found in ~/bin as well.

However, not all of my computers are configured equally. Some run different Linux (or non-Linux) distributions, or have different concerns being desktops, servers, laptops, phones, etc. It’s often useful for this reason to be able to customize my configuration for each host. For example, before $HOME/bin in my $PATH, I have $HOME/bin/$(hostname). I also run several machines on different architectures, so I include $HOME/bin/$(uname -m)1 as well. To customize my sway configuration to consider the different device configurations of each host, I use the following directive in ~/.config/sway/config:

include ~/.config/sway/`hostname`

Then I have a host-specific configuration there, also tracked by git so I can conveniently update one machine from another. I take a similar approach to per-host configuration for many other pieces of software I use.

Rather than using (and learning) any specialized tools, I find my needs quite adequately satisfied by a simple composition of several Unix primitives with a tool I’m already very familiar with: git. Version controlling your configuration files is a desirable trait even with other systems, so why not ditch the middleman?


  1. uname -m prints out the system architecture. Try it for yourself, I bet it’ll read “x86_64” or maybe “aarch64”. ↩︎

Have a comment on one of my posts? Start a discussion in my public inbox by sending an email to ~sircmpwn/public-inbox@lists.sr.ht [mailing list etiquette]

Articles from blogs I read Generated by openring

Willingness to look stupid

People frequently1 think that I'm very stupid. I don't find this surprising, since I don't mind if other people think I'm stupid, which means that I don't adjust my behavior to avoid seeming stupid, which results in people thinking tha…

via Dan Luu October 21, 2021

Status update, October 2021

Hi! Another month, another status update. Let’s dig in! The highlight of this month is the launch of chat.sr.ht, a hosted IRC bouncer service based on soju and gamja. The service is in closed beta for now, feel free to ping me if you want to try it out! It to…

via emersion October 18, 2021

What's cooking on SourceHut? October 2021

Welcome back for another month’s status update! As of today, our community numbers at 25,074 — the first time we’ve had over 25,000 users — after another 522 users joined our ranks. Please show them the courtesey and patience you’ve always done as they learn…

via Blogs on Sourcehut October 15, 2021