Dotfiles and Brewfile maintenance
What to update and when, and how to rebuild a new Mac from the
backup. chezmoi holds the config files; ~/.Brewfile holds
the list of installed packages.
When to update
| You did this | Do this |
|---|---|
brew upgrade |
Nothing. The Brewfile lists names, not versions |
| Installed or removed a package | Refresh the Brewfile |
| Edited a tracked config file | chezmoi re-add the file and push |
| Created a new config file worth keeping | chezmoi add the file and push |
| A tool broke after a major upgrade | Fix the config, then chezmoi re-add and push |
Check for drift any time with chezmoi status. Empty
output means everything matches the repo.
How to update
Packages changed
brew bundle dump --file ~/.Brewfile --force && chezmoi re-add ~/.Brewfile && chezmoi git pushA config file changed
Edited directly:
chezmoi re-add ~/.config/ghostty/config
chezmoi git pushOr edit through chezmoi so it's tracked automatically:
chezmoi edit ~/.config/ghostty/config
chezmoi apply
chezmoi git pushA new file to track
chezmoi add ~/.config/some-tool/config
chezmoi git pushUse chezmoi add --encrypt for anything sensitive.
re-add only works on files chezmoi already tracks.
autoCommit is on, so every add or re-add is committed
automatically. Pushing is manual so you can run gitleaks
first if a change might contain a secret.
One-time: make the config restorable
chezmoi never commits its own
~/.config/chezmoi/chezmoi.toml, so a new Mac wouldn't know
about age encryption or Bitwarden. Commit a template of it instead;
chezmoi init turns it back into the real config. The age
recipient is a public key, so it's safe in the repo.
- Check the recipient matches your key (it must start with
age1):grep 'public key' ~/.config/chezmoi/key.txt grep recipient ~/.config/chezmoi/chezmoi.toml - Test encryption round-trips:
It should print
echo "test" > /tmp/enc-test chezmoi encrypt /tmp/enc-test | chezmoi decrypttest. - Copy the config into the repo as a template and commit it. It's a
new file, so it needs
git add;commit -aalone won't pick it up:cp ~/.config/chezmoi/chezmoi.toml "$(chezmoi source-path)/.chezmoi.toml.tmpl" chezmoi git -- add .chezmoi.toml.tmpl chezmoi git -- commit -m "Add chezmoi config template" chezmoi git push - Confirm it's tracked and pushed:
The log should show
chezmoi git -- log --oneline -3 chezmoi git -- ls-files | grep chezmoi.tomlorigin/mainon the latest commit, and the second command should print.chezmoi.toml.tmpl.
If you change chezmoi.toml later, copy it over the
template again and commit:
cp ~/.config/chezmoi/chezmoi.toml "$(chezmoi source-path)/.chezmoi.toml.tmpl"
chezmoi git -- commit -am "Update chezmoi config template" && chezmoi git pushRebuild a new Mac
The order matters: chezmoi puts ~/.Brewfile back first,
then Homebrew installs from it.
- Install the Xcode command line tools and Homebrew:
xcode-select --install /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" eval "$(/opt/homebrew/bin/brew shellenv)" - Install the bootstrap tools:
brew install chezmoi age bitwarden-cli gh - Restore the age key from Bitwarden (secure note) to
~/.config/chezmoi/key.txt:mkdir -p ~/.config/chezmoi vim ~/.config/chezmoi/key.txt chmod 600 ~/.config/chezmoi/key.txt - Unlock Bitwarden, so templates that pull secrets can render:
bw login export BW_SESSION=$(bw unlock --raw) - Sign in to GitHub and pull everything down:
gh auth login chezmoi init --apply https://github.com/<you>/dotfiles.gitinitcreates~/.config/chezmoi/chezmoi.tomlfrom the committed template, then decrypts and applies everything. - Install every package and app from the Brewfile:
brew bundle --file ~/.Brewfile - Check it all landed:
chezmoi status chezmoi doctor pwsh -c "Get-Command Get-GuestStatus"
Then open a new Ghostty window to pick up the shell and prompt config.
Troubleshooting
Formulae dependency graph sorting found a circular dependency
Stale dependency data from when packages were installed. Harmless for the Brewfile. To clear it:
brew update
brew reinstall libtiff webpchezmoi: ... not managed
The file isn't tracked yet. Use chezmoi add instead of
re-add.
chezmoi init --apply
fails on a Bitwarden template
BW_SESSION isn't set or has expired. Rerun step 4, then
chezmoi apply.
age: error: unknown recipient type
The recipient in chezmoi.toml is mistyped.
age public keys always start with age1; anything else (for
example age2...) is a copy error. Write the correct key in
automatically:
PUB=$(grep 'public key' ~/.config/chezmoi/key.txt | awk '{print $4}')
sed -i '' "s|recipient = \".*\"|recipient = \"$PUB\"|" ~/.config/chezmoi/chezmoi.toml
grep recipient ~/.config/chezmoi/chezmoi.tomlThen rerun the encryption test and update the template (one-time section, step 3).
age: error: failed to read header: parsing age header: file is empty
A knock-on error: encryption failed earlier in the pipe, so
decrypt received nothing. Fix the first error shown.
nothing added to commit but untracked files present
The file is new to git, and commit -a only commits files
git already tracks. Add it first:
chezmoi git -- add <file>
chezmoi git -- commit -m "Add <file>"
chezmoi git pushgitleaks output when committing
Lines like INF no leaks found come from the pre-commit
hook and mean the commit was scanned and is clean. If it reports a leak,
the commit is blocked: remove the secret, move it to Bitwarden or
chezmoi add --encrypt, and commit again.
Encrypted files fail to decrypt
key.txt is missing or wrong, or
chezmoi.toml wasn't generated (the template step was
skipped). Check the key matches the recipient in
~/.config/chezmoi/chezmoi.toml:
grep 'public key' ~/.config/chezmoi/key.txt
grep recipient ~/.config/chezmoi/chezmoi.tomlbrew bundle stops
on one package
Usually a cask that needs a manual approval or has been renamed. Fix
or remove that line in ~/.Brewfile, rerun
brew bundle, then
chezmoi re-add ~/.Brewfile.