Manage your dotfiles securely across multiple machines.
- Concepts
- Global command line flags
- Configuration file
- Source state attributes
- Special files and directories
- Commands
add
targetsapply
[targets]archive
cat
targetscd
chattr
attributes targetscompletion
shelldata
diff
[targets]docs
[regexp]doctor
dump
[targets]edit
[targets]edit-config
execute-template
[templates]forget
targetsgit
[arguments]help
commandhg
[*arguments]init
[repo]import
filenamemanage
targetsmanaged
merge
targetspurge
remove
targetsrm
targetssecret
source
[args]source-path
[targets]unmanage
targetsunmanaged
update
upgrade
verify
[targets]
- Editor configuration
- Umask configuration
- Template execution
- Template variables
- Template functions
chezmoi evaluates the source state for the current machine and then updates the destination directory, where:
-
The source state declares the desired state of your home directory, including templates and machine-specific configuration.
-
The source directory is where chezmoi stores the source state, by default
~/.local/share/chezmoi
. -
The target state is the source state computed for the current machine.
-
The destination directory is the directory that chezmoi manages, by default
~
, your home directory. -
A target is a file, directory, or symlink in the destination directory.
-
The destination state is the state of all the targets in the destination directory.
-
The config file contains machine-specific configuration, by default it is
~/.config/chezmoi/chezmoi.toml
.
Command line flags override any values set in the configuration file.
Colorize diffs, value can be on
, off
, or auto
. The default value is
auto
which will colorize diffs only if the output is a terminal.
Read the configuration from filename.
Log information helpful for debugging.
Use directory as the destination directory.
If the last part of a target is a symlink, deal with what the symlink references, rather than the symlink itself.
Set dry run mode. In dry run mode, the destination directory is never modified.
This is most useful in combination with the -v
(verbose) flag to print changes
that would be made without making them.
Print help.
Also remove targets according to .chezmoiremove
.
Use directory as the source directory.
Set verbose mode. In verbose mode, chezmoi prints the changes that it is making as approximate shell commands, and any differences in files between the target state and the destination set are printed as unified diffs.
Print the version of chezmoi, the commit at which it was built, and the build timestamp.
chezmoi searches for its configuration file according to the XDG Base Directory
Specification
and supports all formats supported by
github.com/spf13/viper
, namely
JSON,
TOML, YAML, macOS
property file format, and HCL. The basename
of the config file is chezmoi
, and the first config file found is used.
The following configuration variables are available:
Variable | Type | Default value | Description |
---|---|---|---|
bitwarden.command |
string | bw |
Bitwarden CLI command |
cd.command |
string | none | Shell to run in cd command |
color |
string | auto |
Colorize diffs |
data |
any | none | Template data |
destDir |
string | ~ |
Destination directory |
diff.format |
string | chezmoi |
Diff format, either chezmoi or git |
diff.pager |
string | none | Pager |
dryRun |
bool | false |
Dry run mode |
follow |
bool | false |
Follow symlinks |
genericSecret.command |
string | none | Generic secret command |
gopass.command |
string | gopass |
gopass CLI command |
gpg.command |
string | gpg |
GPG CLI command |
gpg.recipient |
string | none | GPG recipient |
gpg.symmetric |
bool | false |
Use symmetric GPG encryption |
keepassxc.args |
[]string | none | Extra args to KeePassXC CLI command |
keepassxc.command |
string | keepassxc-cli |
KeePassXC CLI command |
keepassxc.database |
string | none | KeePassXC database |
lastpass.command |
string | lpass |
Lastpass CLI command |
merge.args |
[]string | none | Extra args to 3-way merge command |
merge.command |
string | vimdiff |
3-way merge command |
onepassword.command |
string | op |
1Password CLI command |
pass.command |
string | pass |
Pass CLI command |
remove |
bool | false |
Remove targets |
sourceDir |
string | ~/.local/share/chezmoi |
Source directory |
sourceVCS.autoCommit |
bool | false |
Commit changes to the source state after any change |
sourceVCS.autoPush |
bool | false |
Push changes to the source state after any change |
sourceVCS.command |
string | git |
Source version control system |
template.options |
[]string | ["missingkey=error"] |
Template options |
umask |
int | from system | Umask |
vault.command |
string | vault |
Vault CLI command |
verbose |
bool | false |
Verbose mode |
chezmoi stores the source state of files, symbolic links, and directories in
regular files and directories in the source directory (~/.local/share/chezmoi
by default). This location can be overridden with the -S
flag or by giving a
value for sourceDir
in ~/.config/chezmoi/chezmoi.toml
. Some state is
encoded in the source names. chezmoi ignores all files and directories in the
source directory that begin with a .
. The following prefixes and suffixes are
special, and are collectively referred to as "attributes":
Prefix | Effect |
---|---|
encrypted_ |
Encrypt the file in the source state. |
once_ |
Only run script once. |
private_ |
Remove all group and world permissions from the target file or directory. |
empty_ |
Ensure the file exists, even if is empty. By default, empty files are removed. |
exact_ |
Remove anything not managed by chezmoi. |
executable_ |
Add executable permissions to the target file. |
run_ |
Treat the contents as a script to run. |
symlink_ |
Create a symlink instead of a regular file. |
dot_ |
Rename to use a leading dot, e.g. dot_foo becomes .foo . |
Suffix | Effect |
---|---|
.tmpl |
Treat the contents of the source file as a template. |
Order of prefixes is important, the order is run_
, exact_
, private_
,
empty_
, executable_
, symlink_
, once_
, dot_
.
Different target types allow different prefixes and suffixes:
Target type | Allowed prefixes | Allowed suffixes |
---|---|---|
Directory | exact_ , private_ , dot_ |
none |
Regular file | encrypted_ , private_ , empty_ , executable_ , dot_ |
.tmpl |
Script | run_ , once_ |
.tmpl |
Symbolic link | symlink_ , dot_ , |
.tmpl |
All files and directories in the source state whose name begins with .
are
ignored by default, unless they are one of the special files listed here.
If a file called .chezmoi.<format>.tmpl
exists then chezmoi init
will use it
to create an initial config file. format must be one of the the supported
config file formats.
{{ $email := promptString "email" -}}
data:
email: "{{ $email }}"
If a file called .chezmoiignore
exists in the source state then it is
interpreted as a set of patterns to ignore. Patterns are matched using
doublestar.PathMatch
and match against the target path, not the source path.
Patterns can be excluded by prefixing them with a !
character. All excludes
take priority over all includes.
Comments are introduced with the #
character and run until the end of the
line.
.chezmoiignore
is interpreted as a template. This allows different files to be
ignored on different machines.
.chezmoiignore
files in subdirectories apply only to that subdirectory.
README.md
*.txt # ignore *.txt in the target directory
*/*.txt # ignore *.txt in subdirectories of the target directory
{{- if ne .email "[email protected]" }}
# Ignore .company-directory unless configured with a company email
.company-directory # note that the pattern is not dot_company-directory
{{- end }}
{{- if ne .email "[email protected] }}
.personal-file
{{- end }}
If a file called .chezmoiremove
exists in the source state then it is
interpreted as a list of targets to remove. .chezmoiremove
is interpreted as a
template.
If a directory called .chezmoitemplates
exists, then all files in this
directory are parsed as templates are available as templates with a name equal
to the relative path of the file.
Given:
.chezmoitemplates/foo
{{ if true }}bar{{ end }}
dot_config.tmpl
{{ template "foo" }}
The target state of .config
will be bar
.
If a file called .chezmoiversion
exists, then its contents are interpreted as
a semantic version defining the minimum version of chezmoi required to interpret
the source state correctly. chezmoi will refuse to interpret the source state if
the current version is too old.
Warning support for .chezmoiversion
will be introduced in a future version
(likely 1.5.0). Earlier versions of chezmoi will ignore this file.
1.5.0
Add targets to the source state. If any target is already in the source state,
then its source state is replaced with its current state in the destination
directory. The add
command accepts additional flags:
Automatically generate a template by replacing strings with variable names from
the data
section of the config file. Longer subsitutions occur before shorter
ones. This implies the --template
option.
Set the empty
attribute on added files.
Add targets, even if doing so would cause a source template to be overwritten.
Set the exact
attribute on added directories.
Interactively prompt before adding each file.
Recursively add all files, directories, and symlinks.
Set the template
attribute on added files and symlinks.
chezmoi add ~/.bashrc
chezmoi add ~/.gitconfig --template
chezmoi add ~/.vim --recursive
chezmoi add ~/.oh-my-zsh --exact --recursive
Ensure that targets are in the target state, updating them if necessary. If no targets are specified, the state of all targets are ensured.
chezmoi apply
chezmoi apply --dry-run --verbose
chezmoi apply ~/.bashrc
Write a tar archive of the target state to stdout. This can be piped into tar
to inspect the target state.
chezmoi archive | tar tvf -
Write the target state of targets to stdout. targets must be files or symlinks. For files, the target file contents are written. For symlinks, the target target is written.
chezmoi cat ~/.bashrc
Launch a shell in the source directory. chezmoi will launch the command set by
the cd.command
confiuration varaible. If this is not set, chezmoi will attempt
to detect your shell and will finally fall back to an OS-specific default.
chezmoi cd
Change the attributes of targets. attributes specifies which attributes to
modify. Add attributes by specifying them or their abbreviations directly,
optionally prefixed with a plus sign (+
). Remove attributes by prefixing them
or their attributes with the string no
or a minus sign (-
). The available
attributes and their abbreviations are:
Attribute | Abbreviation |
---|---|
empty |
e |
encrypted |
none |
exact |
none |
executable |
x |
private |
p |
template |
t |
Multiple attributes modifications may be specified by separating them with a
comma (,
).
chezmoi chattr template ~/.bashrc
chezmoi chattr noempty ~/.profile
chezmoi chattr private,template ~/.netrc
Generate shell completion code for the specified shell (bash
, fish
, or
zsh
).
Write the shell completion code to filename instead of stdout.
chezmoi completion bash
chezmoi completion fish --output ~/.config/fish/completions/chezmoi.fish
Write the computed template data in JSON format to stdout. The data
command
accepts additional flags:
Print the computed template data in the given format. The accepted formats are
json
(JSON), toml
(TOML), and yaml
(YAML).
chezmoi data
chezmoi data --format=yaml
Print the difference between the target state and the destination state for targets. If no targets are specified, print the differences for all targets.
If a diff.pager
command is set in the configuration file then the output will
be piped into it.
Print the diff in format. The format can be set with the diff.format
variable in the configuration file. Valid formats are:
A mix of unified diffs and pseudo shell commands, equivalent to chezmoi apply --dry-run --verbose
. They can be colorized and include scripts.
A git format diff, without color and not
including scripts. In version 2.0.0 of chezmoi, git
format diffs will become
the default and support color and scripts and the chezmoi
format will be
removed.
Do not use the pager.
chezmoi diff
chezmoi diff ~/.bashrc
chezmoi diff --format=git
Print the documentation page matching the regular expression regexp. Matching
is case insensitive. If no pattern is given, print REFERENCE.md
.
chezmoi docs
chezmoi docs faq
chezmoi docs howto
Check for potential problems.
chezmoi doctor
Dump the target state in JSON format. If no targets are specified, then the
entire target state. The dump
command accepts additional arguments:
Print the target state in the given format. The accepted formats are json
(JSON) and yaml
(YAML).
chezmoi dump ~/.bashrc
chezmoi dump --format=yaml
Edit the source state of targets, which must be files or symlinks. If no
targets are given the the source directory itself is opened with $EDITOR
. The
edit
command accepts additional arguments:
Apply target immediately after editing. Ignored if there are no targets.
Print the difference between the target state and the actual state after editing.. Ignored if there are no targets.
Prompt before applying each target.. Ignored if there are no targets.
chezmoi edit ~/.bashrc
chezmoi edit ~/.bashrc --apply --prompt
chezmoi edit
Edit the configuration file.
chezmoi edit-config
Write the result of evaluating templates to stdout. This is useful for testing templates or for calling chezmoi from other scripts. templates are interpeted as literal template data, with no whitespace added to the output between arguments. If no templates are specified, the template data are read from stdin.
Include simulated functions only available during chezmoi init
.
Simulate the promptString
function with a function that returns values from
pairs. pairs is a comma-separated list of prompt=
value pairs. If
promptString
is called with a prompt that does not match any of pairs,
then it returns prompt unchanged.
chezmoi execute-template '{{ .chezmoi.sourceDir }}'
chezmoi execute-template '{{ .chezmoi.os }}' / '{{ .chezmoi.arch }}'
echo '{{ .chezmoi | toJson }}' | chezmoi execute-template
chezmoi execute-template --init --promptString [email protected] < ~/.local/share/chezmoi/.chezmoi.toml.tmpl
Remove targets from the source state, i.e. stop managing them.
chezmoi forget ~/.bashrc
Run git
arguments in the source directory. Note that flags in arguments
must occur after --
to prevent chezmoi from interpreting them.
chezmoi git add .
chezmoi git add dot_gitconfig
chezmoi git -- commit -m "Add .gitconfig"
Print the help associated with command.
Run hg
arguments in the source directory. Note that flags in arguments
must occur after --
to prevent chezmoi from interpreting them.
chezmoi hg -- pull --rebase --update
Setup the source directory and update the destination directory to match the
target state. If repo is given then it is checked out into the source
directory, otherwise a new repository is initialized in the source directory. If
a file called .chezmoi.format.tmpl
exists, where format
is one of the
supported file formats (e.g. json
, toml
, or yaml
) then a new configuration
file is created using that file as a template. Finally, if the --apply
flag is
passed, chezmoi apply
is run.
chezmoi init https://github.com/user/dotfiles.git
chezmoi init https://github.com/user/dotfiles.git --apply
Import the source state from an archive file in to a directory in the source
state. This is primarily used to make subdirectories of your home directory
exactly match the contents of a downloaded archive. You will generally always
want to set the --destination
, --exact
, and --remove-destination
flags.
The only supported archive format is .tar.gz
.
Set the destination (in the source state) where the archive will be imported.
Set the exact
attribute on all imported directories.
Remove destination (in the source state) before importing.
Strip n leading components from paths.
curl -s -L -o oh-my-zsh-master.tar.gz https://github.com/robbyrussell/oh-my-zsh/archive/master.tar.gz
chezmoi import --strip-components 1 --destination ~/.oh-my-zsh oh-my-zsh-master.tar.gz
manage
is an alias for add
for symmetry with unmanage
.
List all managed entries in the destination directory in alphabetical order.
Only list entries of type types. types is a comma-separated list of types of
entry to include. Valid types are dirs
, files
, and symlinks
which can be
abbreviated to d
, f
, and s
respectively. By default, manage
will list
entries of all types.
chezmoi managed
chezmoi managed --include=files
chezmoi managed --include=files,symlinks
chezmoi managed -i d
chezmoi managed -i d,f
Perform a three-way merge between the destination state, the source state, and
the target state. The merge tool is defined by the merge.command
configuration
variable, and defaults to vimdiff
. If multiple targets are specified the merge
tool is invoked for each target. If the target state cannot be computed (for
example if source is a template containing errors or an encrypted file that
cannot be decrypted) a two-way merge is performed instead.
chezmoi merge ~/.bashrc
Remove chezmoi's configuration, state, and source directory, but leave the target state intact.
Remove without prompting.
chezmoi purge
chezmoi purge --force
Remove targets from both the source state and the destination directory.
Remove without prompting.
rm
is an alias for remove
.
Run a secret manager's CLI, passing any extra arguments to the secret manager's
CLI. This is primarily for verifying chezmoi's integration with your secret
manager. Normally you would use template functions to retrieve secrets. Note
that if you want to pass flags to the secret manager's CLU you will need to
separate them with --
to prevent chezmoi from interpreting them.
To get a full list of available commands run:
chezmoi secret help
chezmoi secret bitwarden list items
chezmoi secret keyring set --service service --user user
chezmoi secret keyring get --service service --user user
chezmoi secret lastpass ls
chezmoi secret lastpass -- show --format=json id
chezmoi secret onepassword list items
chezmoi secret onepassword get item id
chezmoi secret pass show id
chezmoi secret vault -- kv get -format=json id
Execute the source version control system in the source directory with args.
Note that any flags for the source version control system must be sepeated with
a --
to stop chezmoi from reading them.
chezmoi source init
chezmoi source add .
chezmoi source commit -- -m "Initial commit"
Print the path to each target's source state. If no targets are specified then print the source directory.
chezmoi source-path
chezmoi source-path ~/.bashrc
unmanage
is an alias for forget
for symmetry with manage
.
List all unmanaged files in the destination directory.
chezmoi unmanaged
Pull changes from the source VCS and apply any changes.
chezmoi update
Upgrade chezmoi by downloading and installing the latest released version. This will call the GitHub API to determine if there is a new version of chezmoi available, and if so, download and attempt to install it in the same way as chezmoi was previously installed.
If chezmoi was installed with a package manager (dpkg
or rpm
) then upgrade
will download a new package and install it, using sudo
if it is installed.
Otherwise, chezmoi will download the latest executable and replace the existing
executable with the new version.
If the CHEZMOI_GITHUB_API_TOKEN
environment variable is set, then its value
will be used to authenticate requests to the GitHub API, otherwise
unauthenticated requests are used which are subject to stricter rate
limiting. Unauthenticated
requests should be sufficient for most cases.
chezmoi upgrade
Verify that all targets match their target state. chezmoi exits with code 0 (success) if all targets match their target state, or 1 (failure) otherwise. If no targets are specified then all targets are checked.
chezmoi verify
chezmoi verify ~/.bashrc
The edit
and edit-config
commands use the editor specified by the VISUAL
environment variable, the EDITOR
environment variable, or vi
, whichever is
specified first.
By default, chezmoi uses your current umask as set by your operating system and
shell. chezmoi only stores crude permissions in its source state, namely in the
executable
and private
attributes, corresponding to the umasks of 0o111
and 0o077
respectively.
For machine-specific control of umask, set the umask
configuration variable in
chezmoi's configuration file, for example:
umask = 0o22
chezmoi executes templates using
text/template
. The result is treated
differently depending on whether the target is a file or a symlink.
If target is a file, then:
- If the result is an empty string, then the file is removed.
- Otherwise, the target file contents are result.
If the target is a symlink, then:
- Leading and trailing whitespace are stripped from the result.
- If the result is an empty string, then the symlink is removed.
- Otherwise, the target symlink target is the result.
chezmoi executes templates using text/template
's missingkey=error
option,
which means that misspelled or missing keys will raise an error. This can be
overridden by setting a list of options in the configuration file, for example:
[template]
options = ["missingkey=zero"]
For a full list of options, see
Template.Option
.
chezmoi provides the following automatically populated variables:
Variable | Value |
---|---|
.chezmoi.arch |
Architecture, e.g. amd64 , arm , etc. as returned by runtime.GOARCH. |
.chezmoi.fullHostname |
The full hostname of the machine chezmoi is running on. |
.chezmoi.group |
The group of the user running chezmoi. |
.chezmoi.homedir |
The home directory of the user running chezmoi. |
.chezmoi.hostname |
The hostname of the machine chezmoi is running on, up to the first . . |
.chezmoi.kernel |
Contains information from /proc/sys/kernel . Linux only, useful for detecting specific kernels (i.e. Microsoft's WSL kernel). |
.chezmoi.os |
Operating system, e.g. darwin , linux , etc. as returned by runtime.GOOS. |
.chezmoi.osRelease |
The information from /etc/os-release , Linux only, run chezmoi data to see its output. |
.chezmoi.sourceDir |
The source directory. |
.chezmoi.username |
The username of the user running chezmoi. |
Additional variables can be defined in the config file in the data
section.
Variable names must consist of a letter and be followed by zero or more letters
and/or digits.
All standard text/template
and text
template functions from sprig
are
included. chezmoi provides some additional functions.
bitwarden
returns structured data retrieved from
Bitwarden using the Bitwarden
CLI (bw
). args are passed to bw
unchanged and the output from bw
is parsed as JSON. The output from bw
is
cached so calling bitwarden
multiple times with the same arguments will only
invoke bw
once.
username = {{ (bitwarden "item" "example.com").login.username }}
password = {{ (bitwarden "item" "example.com").login.password }}
gopass
returns passwords stored in gopass using the
gopass CLI (gopass
). gopass-name is passed to gopass show <gopass-name>
and first line of the output of gopass
is returned with the trailing newline
stripped. The output from gopass
is cached so calling gopass
multiple times
with the same gopass-name will only invoke gopass
once.
{{ gopass "<pass-name>" }}
keepassxc
returns structured data retrieved from a
KeePassXC database using the KeePassXC CLI
(keepassxc-cli
). The database is configured by setting keepassxc.database
in
the configuration file. database and entry are passed to keepassxc-cli show
. You will be prompted for the database password the first time
keepassxc-cli
is run, and the password is cached, in plain text, in memory
until chezmoi terminates. The output from keepassxc-cli
is parsed into
key-value pairs and cached so calling keepassxc
multiple times with the same
entry will only invoke keepassxc-cli
once.
username = {{ (keepassxc "example.com").UserName }}
password = {{ (keepassxc "example.com").Password }}
keepassxcAttribute
returns the attribute attribute of entry using
keepassxc-cli
, with any leading or trailing whitespace removed. It behaves
identically to the keepassxc
function in terms of configuration, password
prompting, password storage, and result caching.
{{ keepassxcAttribute "SSH Key" "private-key" }}
keyring
retrieves the password associated with service and user from the
user's keyring.
OS | Keyring |
---|---|
macOS | Keychain |
Linux | GNOME Keyring |
[github]
user = "{{ .github.user }}"
token = "{{ keyring "github" .github.user }}"
lastpass
returns structured data from LastPass using
the LastPass CLI
(lpass
). id is passed to lpass show --json <id>
and the output from
lpass
is parsed as JSON. In addition, the note
field, if present, is further
parsed as colon-separated key-value pairs. The structured data is an array so
typically the index
function is used to extract the first item. The output
from lastpass
is cached so calling lastpass
multiple times with the same
id will only invoke lpass
once.
githubPassword = "{{ (index (lastpass "GitHub") 0).password }}"
{{ (index (lastpass "SSH") 0).note.privateKey }}
lastpassRaw
returns structured data from LastPass
using the LastPass CLI
(lpass
). It behaves identically to the lastpass
function, except that no
further parsing is done on the note
field.
{{ (index (lastpassRaw "SSH Private Key") 0).note }}
onepassword
returns structured data from 1Password
using the 1Password
CLI (op
). uuid
is passed to op get item <uuid>
and the output from op
is parsed as JSON.
The output from op
is cached so calling onepassword
multiple times with the
same uuid will only invoke op
once.
{{ (onepassword "<uuid>").details.password }}
onepassword
returns a document from 1Password
using the 1Password
CLI (op
). uuid
is passed to op get document <uuid>
and the output from op
is returned.
The output from op
is cached so calling onepasswordDocument
multiple times with the
same uuid will only invoke op
once.
{{- onepasswordDocument "<uuid>" -}}
pass
returns passwords stored in pass using
the pass CLI (pass
). pass-name is passed to pass show <pass-name>
and
first line of the output of pass
is returned with the trailing newline
stripped. The output from pass
is cached so calling pass
multiple times with
the same pass-name will only invoke pass
once.
{{ pass "<pass-name>" }}
promptString
takes a single argument is a string prompted to the user, and the
return value is the user's response to that prompt with all leading and trailing
space stripped. It is only available when generating the initial config file.
{{ $email := promptString "email" -}}
[data]
email = "{{ $email }}"
secret
returns the output of the generic secret command defined by the
genericSecret.command
configuration variable with args with leading and
trailing whitespace removed. The output is cached so multiple calls to secret
with the same args will only invoke the generic secret command once.
secretJSON
returns structured data from the generic secret command defined by
the genericSecret.command
configuration variable with args. The output is
parsed as JSON. The output is cached so multiple calls to secret
with the same
args will only invoke the generic secret command once.
vault
returns structured data from Vault using
the Vault CLI (vault
). key is
passed to vault kv get -format=json <key>
and the output from vault
is
parsed as JSON. The output from vault
is cached so calling vault
multiple
times with the same key will only invoke vault
once.
{{ (vault "<key>").data.data.password }}