Skip to main content
Common questions about using chezmoi for everyday dotfile management.
There are five popular approaches for editing dotfiles. Choose the one that fits your workflow:1. Use chezmoi edit (recommended):
chezmoi edit ~/.bashrc
With auto-apply:
chezmoi edit --apply ~/.bashrc
With watch mode (auto-apply on save):
chezmoi edit --watch ~/.bashrc
Benefits: Handles encryption transparently, uses target paths, enables git auto-commit.2. Edit in source directory:
chezmoi cd
vim dot_bashrc
chezmoi diff  # Preview changes
chezmoi apply  # Apply changes
Benefits: Direct file editing, works with any editor, can edit multiple files.3. Open source directory in editor:
chezmoi edit  # Opens source directory
Benefits: Works with IDEs, edit multiple files at once.4. Edit target, then re-add:
vim ~/.bashrc
chezmoi add ~/.bashrc  # or: chezmoi re-add
Benefits: Familiar workflow, edit in place.Note: re-add doesn’t work with templates.5. Edit target, then merge:
vim ~/.bashrc
chezmoi merge ~/.bashrc
Benefits: Resolve conflicts with a merge tool.
If you edit ~/.zshrc directly (without using chezmoi), nothing breaks immediately:Before running chezmoi apply:
  • Your modified ~/.zshrc remains in place
  • Changes persist until you run chezmoi apply
When you run chezmoi apply:
  • chezmoi detects that ~/.zshrc has changed
  • You’ll be prompted what to do
  • Options: overwrite, keep current, or merge
To resolve differences:
# Option 1: Update source state with current file
chezmoi add ~/.zshrc

# Option 2: Use merge tool to resolve
chezmoi merge ~/.zshrc

# Option 3: See differences
chezmoi diff
Best practice: Use chezmoi edit to avoid conflicts, or configure auto-apply to see changes immediately.
Use chezmoi unmanaged to see all files that exist in your home directory but aren’t managed by chezmoi:
# List all unmanaged files
chezmoi unmanaged

# List only unmanaged dotfiles (starting with .)
chezmoi unmanaged | grep '^\.'

# Search for specific patterns
chezmoi unmanaged | grep config
Add multiple files at once:
# Add specific files
chezmoi add ~/.vimrc ~/.tmux.conf

# Add an entire directory
chezmoi add ~/.config/nvim

# Add multiple directories
chezmoi add ~/.config/kitty ~/.config/alacritty
Use chezmoi managed to list all files managed by chezmoi:
# List all managed files
chezmoi managed

# List managed files in a specific directory
chezmoi managed | grep .config/nvim

# Count managed files
chezmoi managed | wc -l
See the source path for a file:
chezmoi source-path ~/.bashrc
# Output: /home/user/.local/share/chezmoi/dot_bashrc
By default, chezmoi only manages files you explicitly add. To ignore files in your source directory, use .chezmoiignore.Create .chezmoiignore in your source directory:
chezmoi cd
cat > .chezmoiignore << 'EOF'
README.md
LICENSE
*.swp
**/*.backup
EOF
Pattern examples:
# Ignore specific file
.config/specific_file

# Ignore all .txt files
*.txt

# Ignore directory
.config/cache/

# Ignore pattern recursively
**/*.log
Machine-specific ignores:
.chezmoiignore
{{- if ne .chezmoi.os "darwin" }}
.config/karabiner
.config/hammerspoon
{{- end }}

{{- if ne .chezmoi.os "linux" }}
.config/i3
.config/sway
{{- end }}
See the reference documentation for full syntax.
You have several options for committing changes:Option 1: Use chezmoi cd (manual):
chezmoi cd
git add .
git commit -m "Update dotfiles"
git push
exit  # Return to previous directory
Option 2: Use chezmoi git (shortcut):
chezmoi git add .
chezmoi git commit -m "Update dotfiles"
chezmoi git push
Note: Use -- before flags:
chezmoi git -- commit -m "Update dotfiles"
chezmoi git -- push --force
Option 3: Auto-commit (automatic):
~/.config/chezmoi/chezmoi.toml
[git]
    autoCommit = true
    autoPush = true
Now chezmoi automatically commits and pushes after:
  • chezmoi add
  • chezmoi edit
  • chezmoi apply (with changes)
See the daily operations guide for details.
Use chezmoi merge to resolve differences with a merge tool:
chezmoi merge ~/.bashrc
This opens your configured merge tool with:
  • Destination: Current file in your home directory (your local changes)
  • Source: File in source state (what chezmoi would apply)
  • Target: What the file would become
Copy the changes you want to keep into the source state, save, and exit.Configure your merge tool:
~/.config/chezmoi/chezmoi.toml
[merge]
    command = "vimdiff"  # or: meld, kdiff3, code, etc.
See the tools guide for merge tool configuration.
No, and you shouldn’t. Here’s why:Why chezmoi is unsuitable for shell history:
  • Every command creates a change
  • Would require a commit for each command
  • Would create thousands of commits per day
  • Shell history changes too rapidly
  • Not practical to sync via git
Use a dedicated tool instead:Atuin is designed specifically for shell history sync:
  • End-to-end encrypted
  • Real-time sync across machines
  • Enhanced search and statistics
  • Works with bash, zsh, fish
Install Atuin with chezmoi:
run_once_install_atuin.sh
#!/bin/bash
curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh | bash
Then use chezmoi to manage Atuin’s configuration file.
If your templates depend on external tools (like curl, jq, etc.), install them with a run_before script:
run_before_00-install-prerequisites.sh
#!/bin/bash
set -eu

# Install curl if not present
if ! command -v curl >/dev/null; then
    sudo apt update
    sudo apt install -y curl
fi

# Install jq if not present
if ! command -v jq >/dev/null; then
    sudo apt install -y jq
fi
Important: Don’t make this script a template (no .tmpl extension), or it will be evaluated before the prerequisites are installed.Inject data via environment variables:If you need to pass data to non-template scripts:
~/.config/chezmoi/chezmoi.toml
[scriptEnv]
    OS = "{{ .chezmoi.os }}"
    ARCH = "{{ .chezmoi.arch }}"
See the scripts guide for details.
Use Go template syntax to escape the delimiters:For single braces:
{{ "{{" }}
{{ "}}" }}
Result:
{{
}}
For complete template expressions:
{{ "{{ .Target }}" }}
Result:
{{ .Target }}
Example use case - documenting templates:
README.md.tmpl
# My Dotfiles

This repository uses chezmoi templates.

Example template syntax: {{ "{{ .chezmoi.hostname }}" }}
Use a run_onchange_after_*.tmpl script that includes the HEAD commit:
run_onchange_after_emacs_d.tmpl
#!/bin/bash

# This comment includes the current HEAD, so the script runs when it changes
# {{ output "git" "-C" (joinPath .chezmoi.homeDir ".emacs.d") "rev-parse" "HEAD" }}

echo "~/.emacs.d updated, running setup..."
~/.emacs.d/bin/doom sync
How it works:
  • The template output includes the git HEAD commit hash
  • When the external repo updates, HEAD changes
  • chezmoi detects the script content changed
  • The script runs automatically
Use a run_onchange_*.tmpl script with the current date/time truncated to your desired period.Run daily:
run_onchange_daily.tmpl
#!/bin/bash

# This comment changes daily, triggering the script
# {{ now | date "2006-01-02" }}

echo "Running daily tasks"
# Your daily tasks here
Run weekly:
run_onchange_weekly.tmpl
#!/bin/bash

# Week number (changes weekly)
# {{ output "date" "+%V" | trim }}

echo "Running weekly tasks"
# Your weekly tasks here
Alternative weekly (template functions):
run_onchange_weekly_alt.tmpl
#!/bin/bash

# Approximate week number
# {{ div now.YearDay 7 }}

echo "Running weekly tasks"
How it works:
  • The comment contains a date that changes daily/weekly
  • chezmoi detects the script content changed
  • The script runs automatically
chezmoi provides completions for bash, zsh, fish, and PowerShell.Bash:
# Add to ~/.bashrc
eval "$(chezmoi completion bash)"
Or install system-wide:
chezmoi completion bash | sudo tee /usr/share/bash-completion/completions/chezmoi
Zsh:
# Add to ~/.zshrc
eval "$(chezmoi completion zsh)"
Or add to fpath:
chezmoi completion zsh > ~/.zsh/completions/_chezmoi
Fish:
chezmoi completion fish | source
Or save permanently:
chezmoi completion fish > ~/.config/fish/completions/chezmoi.fish
PowerShell: Add to your profile:
chezmoi completion powershell | Out-String | Invoke-Expression
Package managers: If you installed via a package manager (brew, apt, etc.), completions may already be installed.
Command-line tools installed with Flatpak must be run with flatpak run. There are two approaches:Approach 1: Wrapper script (recommended):Create a wrapper with the same name as the command:
~/bin/keepassxc-cli
#!/bin/bash
flatpak run --command=keepassxc-cli org.keepassxc.KeePassXC -- "$@"
Make it executable:
chmod +x ~/bin/keepassxc-cli
Ensure ~/bin is in your $PATH. Now chezmoi can find and run keepassxc-cli normally.Approach 2: Direct configuration:For tools with .command and .args config options:
~/.config/chezmoi/chezmoi.toml
[diff]
    command = "flatpak"
    args = ["run", "com.vscodium.codium", "--wait", "--diff"]
The wrapper script approach is recommended because it works with chezmoi doctor and feels more natural.See the tools guide for more details.

Build docs developers (and LLMs) love