I had no clue you could create dotfiles to memorialize your setup! And to be able to recreate it on other machines.
Now that I’ve gotten my own [[Tmux]] and [[VIM]] setups going which I am dependent on, institutionalizing these dotfiles seems to be the way to go.
So apparently there are a number of ways to do this. There are actually tools like chezmoi, yadm, stow, dotbot. As I was reading the docs for dotbot, my head started to spin: TMI! yet another tool to configure/learn. So ChatGPT/Claude to the rescue!
This is a cool, bare-bones way to do it without tooling:
-
Create a bare repo, as in:
git init --bare ~/.dotfiles
I had no idea what creating a repo ‘bare’ meant, so this was a good route for me to take. Something to learn! Turns out a bare repo is a repo in which there is no .git folder and no working folder, meaning there aren’t any files that live in a folder that you check out/in; so you don’t directly edit any files. You only check in/out files! The stuff that’s normally in the .git folder actually exist in the folder itself; (that’s things like HEAD, hooks, objects, refs, etc.).
- Then create an alias to be used specifically for managing these dotfiles:
echo "alias dot='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'" >> ~/.zshrc
source ~/.zshrc
You can invoke this using dot. This alias simplifies working with the dotfiles as the git-dir option tells git where to find the the necessary repo information (files such as HEAD, hooks, objects, refs, etc.) and the work-tree option tells git that the working directory (i.e., where the files to check in/out are) is the HOME folder: ~. So all files within HOME are fair game!
- This is helpful to actually show meaningful status:
dot config --local status.showUntrackedFiles no
If you don’t do this and you execute dot status, it’ll show you EVERY file in your home folder! which you do not want! You only care about tracked files that you explicitly add.
- Here’s how to go about adding and committing files:
dot add .zshrc .gitconfig .vimrc
dot commit -m "Initial dotfiles"
- Then pushing to github
dot remote add origin git@github.com:YOURNAME/dotfiles.git
dot push -u origin main
Porting this to a new setup
On a fresh Mac, you can do this to bring in the dotfiles:
git clone --bare git@github.com:YOURNAME/dotfiles.git ~/.dotfiles
alias dot='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
dot config --local status.showUntrackedFiles no
dot checkout
If there are already dotfiles present, you can do this to back them up first just in case:
mkdir -p ~/.dotfiles-backup
dot checkout 2>&1 | grep -E "\s+\." | awk '{print $1}' | xargs -I{} mv {} ~/.dotfiles-backup/{}
dot checkout
Oh yea: fonts!
So you also want to install something like nerd fonts in your terminal as these dotfiles take advantage of some of their capabilities. You need to brew install these fonts and then make your terminal aware of them (iterm2, ghostty, etc.)
Lesson on Git
Going down this route illuminated me on some git specifics like the difference between:
- git fetch: this merely pulls files down from a remote repository; it doesn’t do anything else like merge them or change the files in your working directory; you can view them and decide what you want to do
- git checkout: this operation doesn’t communicate with the remote server at all; it takes files from your local repo and switches them out in your working directory (as in when you switch branches);
- git pull (which combines git fetch and git merge/rebase): this is the most ‘destructive’ operation; the fetch will update your local repo from the remote one and integrate with your current branch; Then it will update your repo and your working directory by doing a merge; sorta similar to a checkout, as in both operations update your working directory; but git pull does A LOT of work, and you need to be cautious.