Backing Up My Dotfiles Before Midnight

Backing Up My Dotfiles Before Midnight

Tutorials backups dotfiles git terminal

Every year around this time I do the same dumb ritual: I sit down on New Year's Eve, usually with the TV on in the background and nobody watching it, and I go through my laptop like it's a junk drawer. This year's version of that ritual turned into finally fixing something I've been doing wrong since roughly 2015 — how I back up my dotfiles.

If you don't know what a dotfile is, it's basically any of the invisible config files that make your terminal, editor, and shell actually feel like yours instead of some rental car. Your .zshrc, your .gitconfig, your neovim config, your tmux setup. I've rebuilt this stuff from memory after a dead SSD probably four separate times, and every time I swear I'll fix it properly, and every time I don't, until apparently I only do it on December 31st.

The lazy way (what I was doing)

For years my "backup strategy" was a folder called dotfiles-backup-FINAL2 sitting in Dropbox, which is exactly as reliable as it sounds. No version history worth trusting, no easy way to symlink things back into place, just a pile of files I'd copy-paste from when disaster hit. It worked, technically, the same way duct tape works on a windshield.

What I actually set up instead

I went with the bare git repo trick instead of pulling in a tool like chezmoi, mostly because I didn't want to learn a new templating syntax at 11pm on a holiday. The idea is you make a git repo that lives outside your home directory and tracks files inside it without a working tree cluttering everything up:

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

Then you just use dot like normal git. dot add .zshrc, dot commit -m "add zsh aliases", dot push. No symlink farm, no separate repo full of copies that drift out of sync with the real files. The files stay exactly where your programs expect them, and git just quietly tracks the ones you've told it to.

I pushed mine to a private repo and, out of paranoia more than anything, also dumped a copy to an external drive that lives in a drawer, because I do not fully trust any single company to still exist in the shape I need it to be in five years. Call it Y2K brain, I don't care.

One thing that annoyed me: .gitignore doesn't behave the way you'd expect with this setup since your work-tree is your entire home folder. I had to explicitly untrack .cache, .npm, and a handful of application state folders that git kept trying to pick up, or the alias would spend ten minutes crawling your whole filesystem doing nothing useful. If you try this, run dot config --local status.showUntrackedFiles no right away or you'll get a status output longer than your actual dotfiles.

The part that's actually about the new year

I'm not going to pretend this is some profound reset-your-life thing. It's just that January 1st is a genuinely convenient forcing function for chores you'd otherwise put off indefinitely, and "make sure I don't lose three hours of config if my drive dies" is a chore worth doing once a year even if the date is arbitrary. I do the same thing with my browser bookmarks, honestly, and I'm overdue for that one too.

If you've got fifteen minutes free before whatever you're doing tonight, the whole bare-repo setup above takes less time than it took me to write this post. Worth doing before the champagne, not after.

Quick checklist if you're doing this tonight

  • Init the bare repo somewhere outside your home dir's normal git tracking
  • Set the alias, don't skip the showUntrackedFiles no step
  • Add your shell rc file, editor config, and anything with API keys stripped out first
  • Push it somewhere that isn't just your laptop
  • Actually test the restore on a spare machine or VM, not just in your head

See you all on the other side of midnight. 2026, apparently, is a thing that's happening now.