I've started using chezmoi to manage my dotfiles: shell config, Git config, editor settings, aliases, and all those small files that make a machine feel like mine.
The basic idea is simple:
chezmoi source repo ↔ my real $HOME files
But the direction matters.
What chezmoi is
chezmoi is a dotfiles manager. Instead of manually copying .zshrc, .gitconfig, config folders, etc. between machines, you keep a clean source of truth in a Git repo.
By default, chezmoi stores that source here:
~/.local/share/chezmoi
That folder is usually a Git repository.
So there are three places to think about:
$HOME files # the real files used by the system
~/.local/share/chezmoi # chezmoi source repo
GitHub/GitLab remote repo # remote backup/sync
Initialize chezmoi
chezmoi init
This creates the chezmoi source directory:
~/.local/share/chezmoi
Then you can check it:
chezmoi source-path
Add a file to chezmoi
chezmoi add ~/.zshrc
This means:
$HOME → chezmoi source repo
For example:
~/.zshrc
becomes something like:
~/.local/share/chezmoi/dot_zshrc
The weird dot_ name is how chezmoi represents hidden files.
Apply changes
chezmoi apply
This means:
chezmoi source repo → $HOME
So apply is not a backup command. It restores or syncs the repo version into your real home folder.
Useful when:
- setting up a new machine
- restoring your config
- applying edits made in chezmoi
- syncing your dotfiles into
$HOME
Preview changes before applying
chezmoi diff
This shows what would change if you ran:
chezmoi apply
Mental model:
What does chezmoi want to change in my real $HOME files?
Good habit:
chezmoi diff
chezmoi apply
Update chezmoi from files I edited manually
Sometimes I edit the real file directly:
~/.zshrc
Then I want chezmoi to learn those changes.
Use:
chezmoi re-add ~/.zshrc
This means:
$HOME → chezmoi source repo
So:
chezmoi apply # repo → home
chezmoi re-add # home → repo
That distinction is the key.
Git is still manual
After chezmoi re-add, Git is not automatically updated remotely.
You still need:
cd "$(chezmoi source-path)"
git status
git diff
git add .
git commit -m "Update dotfiles"
git push
So chezmoi manages the mapping between your real files and the source repo.
Git manages history and remote sync.
Check the Git remote
git remote -v
This shows where the chezmoi repo is pushed.
Example:
origin git@github.com:user/dotfiles.git (fetch)
origin git@github.com:user/dotfiles.git (push)
Stop managing a file
If I want chezmoi to stop tracking a file but keep the real file in $HOME:
chezmoi forget ~/.zshrc
Meaning:
remove from chezmoi
keep ~/.zshrc
If I want to remove it from chezmoi and delete the real file too:
chezmoi destroy ~/.zshrc
Meaning:
remove from chezmoi
delete ~/.zshrc
Safer default: use forget.
Useful commands summary
chezmoi init
Create the chezmoi source repo.
chezmoi source-path
Show where the chezmoi repo lives.
chezmoi add ~/.zshrc
Start managing a file.
chezmoi re-add ~/.zshrc
Update chezmoi with changes made in the real home file.
chezmoi diff
Preview what apply would change.
chezmoi apply
Copy chezmoi source files into $HOME.
chezmoi managed
List files managed by chezmoi.
chezmoi forget ~/.zshrc
Stop managing a file, but keep it in $HOME.
chezmoi destroy ~/.zshrc
Stop managing a file and delete it from $HOME.
My mental model
The important thing is direction:
chezmoi add = home → repo
chezmoi re-add = home → repo
chezmoi apply = repo → home
chezmoi diff = preview repo → home
chezmoi forget = remove from repo, keep home file
chezmoi destroy = remove from repo, delete home file
And after changing the chezmoi repo:
cd "$(chezmoi source-path)"
git add .
git commit -m "Update dotfiles"
git push
That's the whole workflow: edit, capture, commit, push, and later restore with apply.
