Skip to content

Chezmoi: Source Directory, Usage, and Secrets

~/.local/share/chezmoi is chezmoi’s default source directory. This is the repo where chezmoi stores the desired state of your dotfiles.

For example:

  • ~/.bashrc becomes ~/.local/share/chezmoi/dot_bashrc
  • ~/.gitconfig becomes ~/.local/share/chezmoi/dot_gitconfig

You usually do not edit files in your home directory and commit those directly. Instead, you let chezmoi copy them into the source directory, edit the source state, and then run chezmoi apply to sync the target files back into $HOME.

Start from scratch:

Terminal window
sh -c "$(curl -fsLS get.chezmoi.io)"
chezmoi init
chezmoi cd
git init

Use an existing dotfiles repo:

Terminal window
chezmoi init git@github.com:clintonsteiner/dotfiles.git
chezmoi apply

Preview changes before applying:

Terminal window
chezmoi diff
chezmoi -n -v apply

Add a file from your home directory into chezmoi:

Terminal window
chezmoi add ~/.bash_aliases

Edit the managed version:

Terminal window
chezmoi edit ~/.bash_aliases

Apply the updated source state:

Terminal window
chezmoi apply

Commit the source directory changes:

Terminal window
chezmoi cd
git add .
git commit -m "Update bash aliases"
git push

If you want to inspect the source tree directly:

Terminal window
chezmoi source-path
chezmoi cd

Typical layout:

~/.local/share/chezmoi/
├── dot_bashrc
├── dot_gitconfig
├── private_dot_ssh/
└── .chezmoitemplates/

Useful commands:

Terminal window
chezmoi managed
chezmoi status
chezmoi diff

If you need to keep a real file in the repo but do not want the plaintext committed, configure encryption and add it with --encrypt.

Example using age:

Terminal window
chezmoi age-keygen --output=$HOME/.config/chezmoi/key.txt
~/.config/chezmoi/chezmoi.toml
encryption = "age"
[age]
identity = "~/.config/chezmoi/key.txt"
recipient = "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Then add an encrypted file:

Terminal window
chezmoi add --encrypt ~/.ssh/id_ed25519
chezmoi diff
chezmoi apply

When stored in the source directory, chezmoi keeps the encrypted version there and decrypts it automatically when editing or applying.

A better pattern for many configs is to avoid storing the secret value in the repo at all. Instead, keep the config file as a template and resolve the secret at apply time.

Example with the 1Password CLI:

~/.config/chezmoi/chezmoi.toml
[data]
email = "me@example.com"
Terminal window
chezmoi add --template ~/.gitconfig
~/.local/share/chezmoi/dot_gitconfig.tmpl
[user]
email = {{ .email | quote }}
[github]
token = {{ onepasswordRead "op://Personal/GitHub/token" | quote }}

Then apply:

Terminal window
chezmoi diff
chezmoi apply

If you do not use 1Password, chezmoi also supports other secret backends and generic secret commands. The main idea is the same:

  1. Keep the file in ~/.local/share/chezmoi as a template.
  2. Resolve the secret during chezmoi apply.
  3. Do not commit plaintext credentials into the repo.

For most setups:

  • Use --encrypt for small numbers of private files you truly need stored in the repo.
  • Use templates plus a password manager for API keys, tokens, and machine-specific credentials.