Skip to main content

Managing dotfiles with chezmoi

· 4 min read
Pere Pages
Software Engineer

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.

Chezmoi Logo

https://www.chezmoi.io/

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.