homegit
I use a system I call homegit to manage config files and scripts in my home directory on all my machines. The idea is simple: a Git repository rooted at ~
that I push to GitHub. I’ve used this system for 6 years and like it a lot. See below to set it up for yourself!
The core functionality comes from 3 lines in my ~/.bashrc
:
homegit() {
git --git-dir=$HOME/.homegit --work-tree=$HOME "$@"
}
This defines a command homegit
that works like regular git
except that it saves its state in ~/.homegit
(as opposed to ~/.git
). Having a special command helps avoid accidents, like thinking I’m in a project repo, running git clean -dfx
, and deleting everything in my home. I also use git_prompt_info
in my Zsh PS1
to show my current Git branch, and by using --git-dir=$HOME/.homegit
I avoid seeing branch information all the time.
I also define this command:
homegit-private() {
git --git-dir=$HOME/.homegit-private --work-tree=$HOME "$@"
}
homegit-private
works just like homegit
, with the same Git toplevel dir (!) The difference is that I push the contents to a private repo. This allows me to version things like my SSH config and easily keep it in sync across devices. It’s also where I put anything that isn’t the same between my home and work setups.
When I want to pull my dotfiles onto a new device, I run these commands:
git clone git@github.com:kerrickstaley/homedir
mv homedir/.git ~/.homegit
git --git-dir=$HOME/.homegit diff # check that the next command won't overwrite anything
git --git-dir=$HOME/.homegit reset --hard HEAD
The last piece that helps with all this is the runningon
command. This allows me to put conditional blocks in my rc files like this:
# Default to Gnu binaries on macOS.
if runningon macos; then
export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH" # coreutils
export PATH="/opt/homebrew/opt/grep/libexec/gnubin:$PATH" # grep
export PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH" # sed
export PATH="/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH" # tar
fi
That way, I can use the same rc files on both macOS and Linux, at both home and work.
If you want to use this system yourself, you just need to copy these 7 lines into your .bashrc
or .zshrc
, and copy the runningon
script into your ~/bin
and modify the list of hostnames.
Update 2023-11-25:
The vcs-home wiki page links to many other approaches to this idea.
To avoid messy git status
output, I’ve run
homegit config status.showUntrackedFiles no
homegit-private config status.showUntrackedFiles no
on all my machines as suggested in this HN post.