7 months later and I’m happy I chose Chezmoi. I’m managing dotfiles across 3 machines and 2 OS’s currently. I have a basic workflow and it seems like a good time to see if there are further benefits to be found. This is a review of my workflow and some notes on how to use the tool more effectively.
cm in this article and on all my machines.
Including files or subdirectories from other projects is really interesting and something I didn’t realise was possible. It goes a long way to bridging the gap between simple dotfiles management and something more powerful like Ansible.
Next steps (in another 7 months?) would be to use templates and make use of the secrets management capabilities.
cm inityou create a new git repo in
~/.local/share/chezmoi. This is where the source state lives. It’s a repo, so you can do all the usual vcs things you’d expect, but cm won’t do it for you (by default).
cm edit-configopens the configuration file for editing.
Include dotfiles from other projects
.chezmoiexternal.tomlto tell cm to import dotfiles from a different repo. See below for an example
You can’t include subdirectories from other projects like
oh-my-zshbecause you can’t use git submodules (cm uses its own format for the source state).
The section heading (the part with square brackets) is the destination path of the object being imported.
typeis “archive” for collections of files (projects) and “file” for individual files. If the url is a tarball then cm will unpack it.
The default value for
refreshPeriodis never. Cm caches downloaded archives locally to avoid downloading them every time
applyis called. To force a refresh, call
cm --refresh-externals applyor
cm -R apply.
Oh My Zsh, make sure you disable auto-updates by setting
~/.zshrc. Auto updates will cause the
~/.oh-my-zshdirectory to drift out of sync with cm’s source state. Refresh the downloads (by setting
refreshPeriod) to update Oh My Zsh and its plugins.
Adding files and directories
You add a file to cm with
cm add <file>. This copies the file into the source state but changes the name. If the file you want to track is
~/.zshrcthen cm will create a file in the source state called
cm add <dir>just like you can
cm add <file>. If you copy a directory into the source state, the name of the source state copy will be prepended with
dot_, too. The names of the files and dirs inside the directory are not changed.
Which files are tracked, not tracked or ignored
cm managedshows a list of manged files
cm unmanagedshows a list of unmanaged files. You can add entire directories with
.chezmoiignorecontains a list of files that won’t be copied from the source directory to the destination when you run
cm apply. This is the opposite of my intuition [documentation].
cm applycan change so much stuff, try
cm apply --dry-run --verbosefirst.
.chezmoiignoreis a template, so you can ignore different files on different machines.
Editing tracked files
cm diff will show you what changes would be applied if your ran
from the perspective of the source state (Green ⇒ added to source state).
cm apply will overwrite local changes (after prompting for confirmation) with
the copy from the source state.
You can resolve differences if things get messy with
cm merge $FILE.
There are 4 ways of editing files:
chezmoi edit $FILE- opens \$FILE in the editor.
cm editwill open the source state directory. You can also use
cm edit --apply $FILEto apply the changes as soon as you close the file.
cm cdand then edit the files directly. Then
cm applyto apply the changes.
cm diffwill show you what changes would be made by running
cm apply, from the perspective of the source state. (Green means added to the source state, red is removed. This is the opposite of my intuition).
Edit the file in the home directory and then re-add it using
cm add $FILEor
cm re-add(re-add doesn’t work with templates). I’ve created an alias to re-add all files that have been changed
Edit the file in the home directiry and then merge the changes into the source state with
cm merge $FILE.
Importing an entire project:
Oh My Zsh, the
zsh-syntax-highlighting plugin, and
powerlevel10k by putting the following in
[".oh-my-zsh"] type = "archive" url = "https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz" exact = true stripComponents = 1 refreshPeriod = "168h" [".oh-my-zsh/custom/plugins/zsh-syntax-highlighting"] type = "archive" url = "https://github.com/zsh-users/zsh-syntax-highlighting/archive/master.tar.gz" exact = true stripComponents = 1 refreshPeriod = "168h" [".oh-my-zsh/custom/themes/powerlevel10k"] type = "archive" url = "https://github.com/romkatv/powerlevel10k/archive/v1.15.0.tar.gz" exact = true stripComponents = 1
Importing a single file from another project
~/.vim/autoload/plug.vim add this to
[".vim/autoload/plug.vim"] type = "file" url = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" refreshPeriod = "168h"
Most of this was taken directly from the documentation.