Using Git to Manage Dotfiles and Configs
I wanted to get all my dotfiles and config sprawl into version control and ran into a small problem with subdirectories that wasn’t intuitive. This guide is meant to put configs into version control (not recommended for files with secrets).
Setup
- Navigate to your home directory (
cd
without arguments) - Initialize git (
git init
) - Create a .gitignore file (
touch .gitignore
) - (Optional) add a remote (e.g. Github) to back up these files
Gitignore
The purpose of gitignore is to ignore files from getting committed. We want to turn that upside down and use it to include specific files.
Exclude all files
Start with a global exclude:
# .gitignore
*
Include files (root)
By doing that, running git status
shouldn’t show any untracked files. We then want to begin adding the files we want. To do this, use the negation pattern (e.g. !some_file.txt
).
# .gitignore
# ...
!.gitignore
!.bashrc
!.zshrc
Now if you save that, you should see these 3 files (if you have them) untracked.
Include files (subdirectory)
Continuing this trend, let’s add our VSCode settings. This is in a subdirectory, so you would think you could just !some/path/to/settings.json
but that will not work. We instead need to negate every directory leading up to that file, as well as the file.
# .gitignore
# ...
# VSCode
!Library/
!Library/Application Support/
!Library/Application Support/Code/
!Library/Application Support/Code/User/
!Library/Application Support/Code/User/settings.json
When all is said in done, you can have a gitignore that is opt-in, to manage the configs you care about.
Full example from my config:
# .gitignore
# Exclude everything by default
*
# Re-include specific files with negation pattern
!.gitignore
!.bashrc
!.vimrc
!.zshrc
!.zprofile
!antigen.zsh
!.zshenv
!.p10k.zsh
!.kind_config.yaml
# Include specific directories and files within them
# Make sure to include every part of the path
# VSCode
!Library/
!Library/Application Support/
!Library/Application Support/Code/
!Library/Application Support/Code/User/
!Library/Application Support/Code/User/settings.json
# AWS
!.aws/
!.aws/config
You can now commit your files and keep track of future changes (or revert if you accidentally wipe out something useful).
List files in the repo
As the repo grows, you might want to output all the files you’re managing. To get this, run:
git ls-tree -r main --name-only
# example from my output
.bashrc
.gitignore
.kind_config.yaml
.p10k.zsh
.vimrc
.zprofile
.zshenv
.zshrc
Library/Application Support/Code/User/settings.json
antigen.zsh