-
@ [ARCHIVED] Jay
2024-05-19 02:25:59chezmoi
is a command-line tool that usesgit
to keep your dotfiles in sync across all of your machines. In this guide, I'll show you a simple use case of keeping dotfiles synced between two machines,machine_A
andmachine_B
.chezmoi
has many more features that you can explore beyond this as you become more comfortable with the workflow.Chezmoi Cheatsheet
This is a diagram of the various locations
chezmoi
accesses to manage your dotfiles, as well as the relevant commands to move files around. I'll be referencing the locationshome_A
,chezmoi_A
,home_B
,chezmoi_B
, andrepo
shown in this diagram throughout this guide.Installation
The first step to using
chezmoi
is installing and initializing it. We will be onmachine_A
to start with. Here, I'll be building the binary from the source code.First, make sure you have
golang
installed: https://go.dev/doc/installThen, clone the
chezmoi
repo and usemake
to build it:bash cd /tmp git clone https://github.com/twpayne/chezmoi.git cd chezmoi make build
This will create the
chezmoi
binary, which you can then copy any directory in yourPATH
. Here, I'll move it to~/bin
. If~/bin
doesn't exist, you have to create it and re-source~/.profile
to add it toPATH
.bash mkdir -p ~/bin && source ~/.profile cp chezmoi ~/bin/chezmoi
Now you should be able to run
chezmoi
:```bash
chezmoi --version chezmoi version dev, commit 255846 . . . ```
Initialization
Now that you've installed
chezmoi
, you have to initialize it. This guide uses themain
branch for all git operations, and you can change the default branch for git repositories as follows before you initializechezmoi
:bash git config --global init.defaultBranch main
Then initialize
chezmoi
:bash chezmoi init
This creates the
chezmoi
git repository at~/.local/share/chezmoi
. Based on the diagram above, this is the location corresponding tochezmoi_A
.Adding your first file
Most systems have a
.bashrc
or similar configuration file, so that can be the first dotfile you add tochezmoi
:bash chezmoi add ~/.bashrc
Change into the
chezmoi_A
directory to see the file added tochezmoi
:bash chezmoi cd ls
You'll see
dot_bashrc
listed.chezmoi
renames the dots at the start of all of your dotfiles as'dot_'
so they are not considered hidden. This directory is a git repository as well, but it isn't linked to an online repository yet. You can use a private repository on GitHub or GitLab, or even a self-hosted instance of GitLab. Whatever remote repository you choose to use, follow its instructions to create a new repository calleddotfiles
and add it asorigin
to your localchezmoi
git repository. Here, I'll create a private GitHub repository and link it using ssh. Then you should be able to see it with:```bash
git remote -v origin git@github.com:wisehodl/dotfiles.git (fetch) origin git@github.com:wisehodl/dotfiles.git (push) ```
Now commit your first dotfile and push it to the online repo:
bash git add dot_bashrc git commit -m "Added .bashrc" git push -u origin main
Congratulations! You've successfully backed up your first dotfile using
chezmoi
.chezmoi add
can add individual files as well as directories.Adding directories and ignoring files.
chezmoi
can add whole directories withchezmoi add
but you may want to ignore certain files if they are auto-generated or contain sensitive information. Say you have a directory you want to add tochezmoi
that contains some authentication details as well as actual config files, like so:bash /home/wise/.test/ ├── .auth └── .config
Here, we want to add
.test
tochezmoi
but ignore the.auth
file that contains some login information. First, you'll have to tellchezmoi
to ignore the.auth
file using the.chezmoiignore
file. It works just like.gitignore
if you're familiar with that.bash echo ".test/.auth" >> .chezmoiignore
Now you can add the
.test
directory:```bash
chezmoi add ~/.test chezmoi: warning: ignoring .test/.auth ```
And you'll see that
chezmoi
is purposely ignoring the.auth
file. If you look at yourchezmoi
directory now, you'll see thedot_test
directory added with only the config file.Add these changes to your git repo:
bash git add -A git commit -m "Added .test/" git push
Here, you should start to get a feel for how the workflow for adding files to
chezmoi
typically goes. Before we start modifying files, let's move over tomachine_B
and sync your dotfiles over there.Syncing to another machine
For the sake of simplicity, I'll assume that you are syncing your dotfiles to a fresh install of the same Linux distro as
machine_A
. If you have a lot of conflicting dotfiles betweenmachine_A
andmachine_B
, you'll either need to utilizegit merge
orchezmoi merge
at your discretion and resolve the conflicts. If certain files do need to be different between the machines, then you'll have to utilizechezmoi
's templating capabilities. These situations are beyond the scope of this guide and are left as an exercise for the reader.On
machine_B
follow the steps above to install and initializechezmoi
. Then, add your remote git repository as before, and pull it into thechezmoi
directory:bash git pull origin main
The first time you push from
chezmoi_B
, you may have to rungit push -u origin main
to set the upstream branch and fully set up the remote connection.Now to review, we've synced up 4 out of the 5 locations in the diagram above:
home_A
,chezmoi_A
,repo
, andchezmoi_B
. Syncingchezmoi_B
andhome_B
is where things can get complicated if, like I said before, you have a lot of file conflicts. You can check for differences between the source directory,chezmoi_B
and the destination directory,home_B
usingchezmoi diff
. There is also the concept of a "target state" inchezmoi
, but it only becomes relevant if you use templates. In the context of this guide, the source directory is also the target state.Say, for example, you had some conflicting lines in
~/.bashrc
,chezmoi diff
would show you the changes that would need to occur to make the destination state,~/.bashrc
, match the source state,~/.local/share/chezmoi/dot_bashrc
. There are a few strategies you can use to resolve this conflict:- Create a new branch in
chezmoi_B
, add the file fromhome_B
withchezmoi add
, then perform agit merge
back to main. - Use
chezmoi merge ~/.bashrc
, which will take you into avimdiff
window to manually change the files to match. - Overwrite the source file with the destination file using
chezmoi add ~/.bashrc
- Overwrite the destination file with the source file using
chezmoi apply ~/.bashrc
[DANGER AHEAD]
This guide will go with option 4 for every file in
chezmoi_B
:```bash
Do not do this unless you want to OVERWRITE files in your
home directory.
chezmoi apply ```
chezmoi
will do its best to warn you if you're about to do something dangerous and give you some options on how to proceed.Doing this, the dotfiles in both
machine_A
andmachine_B
are in sync! But you know that your dotfiles will change and grow over time, so we have to talk about strategies for maintaining this sync.Modifying your dotfiles
You have to remain mindful that you're using
chezmoi
to keep your dotfiles in sync, otherwisemachine_A
andmachine_B
can get out of sync pretty easily.chezmoi
has thechezmoi edit
command to edit files in the destination state, but I prefer to edit files in eitherhome_A
orhome_B
and then follow the path in the diagram above from end to end to sync up the whole network.For example, you can change or add a file from
home_B
and do:(home_B) $ chezmoi add ~/path/to/.file
(home_B) $ chezmoi cd
(chezmoi_B) $ git add -A
(chezmoi_B) $ git commit -m "Changed ~/path/to/.file"
(chezmoi_B) $ git push
(home_A) $ chezmoi cd
(chezmoi_A) $ git pull
(chezmoi_A) $ chezmoi apply
And that will propagate the change across your network. You can also use
chezmoi update
fromhome_A
to pull the repo and apply the target state all in one step. The best way to avoid conflicts and headaches is to always push changes you make to you dotfiles as soon as you can and avoid making changes to the same file on two different machines simultaneously, just like with any git repository.Conclusion
If you've followed the steps in this guide, you will have learned a workflow to keep the dotfiles between two Linux machines in sync using
chezmoi
. The diagram at the top of the guide should serve as a useful cheatsheet for the most common tasks you'll perform to maintain your dotfiles.chezmoi
is a very versatile application, and is capable of managing very complex dotfile setups. Their documentation is very technical and daunting to the new user, but it remains a good resource for doing more complex tasks withchezmoi
.- Command Overview: https://www.chezmoi.io/user-guide/command-overview/
- Reference: https://www.chezmoi.io/reference/
All the best!
- WiseHODL
- Create a new branch in