Files
lenovo-gentoo/Dotfiles-Management.md

17 KiB

Dotfile Management with chezmoi

Complete guide to managing your dotfiles with chezmoi on this Gentoo workstation and across multiple machines.

Table of Contents


Overview

What is chezmoi?

chezmoi is a cross-platform dotfile manager that allows you to:

  • Keep your dotfiles in a git repository
  • Sync configs across multiple machines (Gentoo, macOS, Ubuntu, etc.)
  • Use templates for machine-specific configurations
  • Manage secrets securely
  • Automate setup on new machines

Current Setup

Dotfiles Repository: ~/repository/git.hinrichs.dev/alexander/dotfiles

  • This is your main git repository
  • Contains all your dotfiles and chezmoi configuration
  • Pushed to your Gitea server

Chezmoi Source Directory: ~/.local/share/chezmoi

  • Git clone of your dotfiles repository
  • Working directory for chezmoi
  • Where you make changes before applying them

Chezmoi Config: ~/.config/chezmoi/chezmoi.yaml

  • Generated from .chezmoi.yaml.tmpl
  • Contains your machine-specific values (name, email, work/personal, etc.)

How It Works

┌─────────────────────────────────────────────────┐
│  1. Edit dotfiles in chezmoi source            │
│     chezmoi edit ~/.zshrc                       │
│     (edits ~/.local/share/chezmoi/dot_zshrc)    │
└─────────────────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────┐
│  2. Preview changes                             │
│     chezmoi diff                                │
└─────────────────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────┐
│  3. Apply to home directory                     │
│     chezmoi apply                               │
│     (copies to ~/.zshrc)                        │
└─────────────────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────┐
│  4. Commit and push                             │
│     chezmoi cd                                  │
│     git add . && git commit && git push         │
└─────────────────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────┐
│  5. Pull on other machines                      │
│     chezmoi update                              │
└─────────────────────────────────────────────────┘

Quick Reference

Task Command
Edit dotfile chezmoi edit ~/.zshrc
Preview changes chezmoi diff
Apply changes chezmoi apply
Add new file chezmoi add ~/.newfile
Go to source dir chezmoi cd
Update from git chezmoi update
List managed files chezmoi managed
Show status chezmoi status
View rendered template chezmoi cat ~/.zshrc

Daily Workflow

Scenario 1: Edit Existing Config

Goal: Update your shell configuration

# 1. Edit the file
chezmoi edit ~/.zshrc

# 2. Preview what will change
chezmoi diff

# 3. Apply the changes
chezmoi apply

# 4. Test the changes
source ~/.zshrc

# 5. If everything works, commit
chezmoi cd
git add dot_zshrc.tmpl  # or dot_zshrc if not a template
git commit -m "feat: add new shell alias"
git push

Scenario 2: Update Neovim Config

Goal: Modify Neovim configuration

# 1. Edit the config
chezmoi edit ~/.config/nvim/lua/alxndrhi/options.lua

# 2. Preview
chezmoi diff

# 3. Apply
chezmoi apply

# 4. Test in neovim
nvim

# 5. Commit
chezmoi cd
git add dot_config/nvim/lua/alxndrhi/options.lua
git commit -m "feat: update neovim tab settings"
git push

Scenario 3: Pull Latest Changes

Goal: Sync dotfiles from another machine

# Pull and apply in one command
chezmoi update

# Or step by step:
chezmoi cd
git pull
exit
chezmoi apply

# Restart affected services
source ~/.zshrc  # If shell config changed
# or restart terminal

Adding New Tools

When you install a new CLI tool or application with configuration files, here's how to add it to your dotfiles.

Example: Adding a New Tool (e.g., 'alacritty')

Step 1: Install the tool

# Install via package manager
sudo emerge -av x11-terms/alacritty

Step 2: Create and test the configuration

# Create config directory
mkdir -p ~/.config/alacritty

# Create config file
nvim ~/.config/alacritty/alacritty.toml

# Test the tool
alacritty --version
alacritty  # Launch and verify config works

Step 3: Add configuration to chezmoi

# Add the config file
chezmoi add ~/.config/alacritty/alacritty.toml

# Or add entire directory
chezmoi add --recursive ~/.config/alacritty

What this does:

  • Copies ~/.config/alacritty/ to ~/.local/share/chezmoi/dot_config/alacritty/
  • File is now managed by chezmoi

Step 4: Verify it was added

# Check if file is managed
chezmoi managed | grep alacritty

# View the source file
chezmoi cd
ls -la dot_config/alacritty/

Step 5: Commit to git

chezmoi cd
git add dot_config/alacritty/
git commit -m "feat: add alacritty terminal emulator configuration"
git push

Step 6: Test on another machine

# On another machine
chezmoi update

# Verify alacritty config is there
ls -la ~/.config/alacritty/

Adding Shell Scripts

If you have custom scripts in ~/bin or ~/.local/bin:

# Add entire directory
chezmoi add --recursive ~/.local/bin

# Or individual scripts
chezmoi add ~/.local/bin/my-script.sh

# Make sure they're executable
chezmoi chattr +executable ~/.local/bin/my-script.sh

# Commit
chezmoi cd
git add .
git commit -m "feat: add custom shell scripts"
git push

Editing Existing Configs

Edit and Apply

# Edit any managed file
chezmoi edit ~/.gitconfig

# This opens: ~/.local/share/chezmoi/dot_gitconfig.tmpl
# (or dot_gitconfig if not a template)

# After editing, preview changes
chezmoi diff

# Apply
chezmoi apply

# Test
git config --list

Edit Multiple Files

# Edit several files in your editor
chezmoi edit ~/.zshrc ~/.gitconfig ~/.config/starship.toml

# Preview all changes
chezmoi diff

# Apply all
chezmoi apply

# Commit all
chezmoi cd
git add .
git commit -m "feat: update shell and git configs"
git push

Edit Directly in Source Directory

# Go to chezmoi source
chezmoi cd

# Edit files directly
nvim dot_zshrc.tmpl
nvim dot_config/nvim/init.lua

# Preview from anywhere
chezmoi diff

# Apply from anywhere
chezmoi apply

# Commit
git add .
git commit -m "feat: update configs"
git push

Templates for Cross-Platform Configs

Some configs need to be different on different operating systems or machines. Use templates for this.

Convert a File to Template

# Make a file a template
chezmoi chattr +template ~/.zshrc

# This renames: dot_zshrc → dot_zshrc.tmpl

Template Syntax

Templates use Go's text/template syntax:

# OS detection
{{ if eq .chezmoi.os "darwin" -}}
# macOS-specific config
export PATH="/opt/homebrew/bin:$PATH"
{{- else if eq .chezmoi.os "linux" -}}
# Linux-specific config
export PATH="/usr/local/bin:$PATH"
{{- end }}

# Distribution detection
{{ if eq .osid "linux-gentoo" -}}
# Gentoo-specific config
alias emerge-update="sudo emerge --sync && sudo emerge -uDNav @world"
{{- else if eq .osid "linux-ubuntu" -}}
# Ubuntu-specific config
alias apt-update="sudo apt update && sudo apt upgrade"
{{- end }}

# Work vs Personal
{{ if .work -}}
# Work-specific config
export COMPANY_DOMAIN="company.com"
{{- else if .personal -}}
# Personal config
export PROJECTS_DIR="$HOME/repository"
{{- end }}

# Machine-specific
{{ if eq .machine "gentoo-workstation" -}}
# Workstation config
export DISPLAY=:0
{{- else if eq .machine "macos-laptop" -}}
# Laptop config
{{- end }}

Available Template Variables

# View all available data
chezmoi data

# Common variables:
.chezmoi.os              # darwin, linux, windows
.chezmoi.osRelease.id    # gentoo, ubuntu, arch
.chezmoi.hostname        # lenovo-thinkpad
.osid                    # linux-gentoo, darwin, etc.
.machine                 # gentoo-workstation, macos-laptop
.work                    # true/false
.personal                # true/false
.email                   # your@email.com
.name                    # Your Name
.features.desktop        # true/false
.features.development    # true/false
.features.docker         # true/false

Example: Cross-Platform .zshrc

# Edit the template
chezmoi edit ~/.zshrc

# Add OS-specific paths
{{ if eq .chezmoi.os "darwin" -}}
# macOS Homebrew
export PATH="/opt/homebrew/bin:$PATH"

# macOS-specific aliases
alias update="brew update && brew upgrade"
{{- else if eq .osid "linux-gentoo" -}}
# Gentoo paths
export PATH="/usr/local/bin:$HOME/.local/bin:$PATH"

# Gentoo-specific aliases
alias update="sudo emerge --sync && sudo emerge -uDNav @world"
{{- end }}

# Common config (works on all platforms)
export EDITOR=nvim
export VISUAL=nvim

# Apply
chezmoi apply

# Test
echo $PATH

View Rendered Template

# See how template renders on this machine
chezmoi cat ~/.zshrc

# Test specific template expression
chezmoi execute-template "{{ .chezmoi.os }}"
chezmoi execute-template "{{ .osid }}"

Syncing Across Machines

Setup on New Machine

One-line install (if you have the bootstrap script):

sh -c "$(curl -fsLS https://git.hinrichs.dev/alexander/dotfiles/raw/branch/main/install.sh)"

Manual setup:

# 1. Install chezmoi
# (see installation instructions for your OS)

# 2. Initialize with your dotfiles repo
chezmoi init https://git.hinrichs.dev/alexander/dotfiles.git

# 3. Preview what will be applied
chezmoi diff

# 4. Apply dotfiles
chezmoi apply

# 5. Restart shell
exec zsh

Keep Machines in Sync

On Machine A (where you made changes):

# Edit configs
chezmoi edit ~/.zshrc

# Apply
chezmoi apply

# Commit and push
chezmoi cd
git add .
git commit -m "feat: update shell config"
git push

On Machine B (pull the changes):

# Pull and apply
chezmoi update

# Or step by step:
chezmoi cd
git pull
exit
chezmoi apply

# Restart shell if needed
exec zsh

Advanced Usage

Ignore Files Per Machine

Edit .chezmoiignore to exclude files on specific machines:

chezmoi cd
nvim .chezmoiignore

# Example content:
{{ if not .features.desktop -}}
# Ignore desktop configs on servers
.config/hypr/
.config/waybar/
{{- end }}

{{ if eq .chezmoi.os "darwin" -}}
# Ignore Linux-specific configs on macOS
.config/systemd/
{{- end }}

Run Scripts on Apply

Create scripts that run when applying dotfiles:

chezmoi cd
nvim .chezmoiscripts/run_once_after_setup-tool.sh

#!/bin/sh
# Install tool if not present
if ! command -v tool >/dev/null 2>&1; then
  echo "Installing tool..."
  # Installation commands
fi

Script naming:

  • run_once_* - Runs once (tracked by hash)
  • run_onchange_* - Runs when script content changes
  • run_before_* - Runs before applying
  • run_after_* - Runs after applying

Encrypt Sensitive Files

# Add encrypted file
chezmoi add --encrypt ~/.ssh/id_rsa

# chezmoi uses age or gpg for encryption

Dry Run / Testing

# See what would change without applying
chezmoi apply --dry-run --verbose

# Test on a VM before applying to main machine

Troubleshooting

Warning: Config File Template Changed

Error: chezmoi: warning: config file template has changed

Solution:

chezmoi init
# Answer prompts for name, email, work/personal

Diff Shows Too Much / Opens vim

The default diff tool is nvim -d. To use built-in diff:

# Use built-in diff (easier to read)
chezmoi diff --use-builtin-diff

# Or use it with pager
chezmoi diff --use-builtin-diff | less

File Conflicts

Error: File already exists and differs

Solution:

# Merge manually
chezmoi merge ~/.zshrc

# Or force overwrite
chezmoi apply --force

# Or remove from management and re-add
chezmoi forget ~/.zshrc
# Fix the file manually
chezmoi add ~/.zshrc

Template Errors

Error: Template syntax error

Solution:

# View raw template
chezmoi cd
cat dot_zshrc.tmpl

# Check template syntax
chezmoi cat ~/.zshrc

# Test specific expression
chezmoi execute-template "{{ .chezmoi.os }}"

Reset Everything

# Remove all managed files (DESTRUCTIVE!)
chezmoi purge

# Start fresh
chezmoi init https://git.hinrichs.dev/alexander/dotfiles.git
chezmoi apply

Re-run Installation Scripts

# Reset script state (scripts will run again)
chezmoi state reset --bucket=scriptState

# Re-apply
chezmoi apply

Check Configuration

# View chezmoi data
chezmoi data | less

# View config file
cat ~/.config/chezmoi/chezmoi.yaml

# Edit config
chezmoi edit-config

Common Patterns

Pattern 1: Update Tool on All Machines

# On your main machine
chezmoi edit ~/.config/tool/config
chezmoi apply
chezmoi cd
git add . && git commit -m "feat: update tool config" && git push

# On other machines
chezmoi update

Pattern 2: Add New Tool

# Install and configure
sudo emerge tool
nvim ~/.config/tool/config

# Add to chezmoi
chezmoi add --recursive ~/.config/tool
chezmoi cd
git add . && git commit -m "feat: add tool configuration" && git push

Pattern 3: Machine-Specific Config

# Edit template
chezmoi edit ~/.zshrc

# Add machine-specific logic
{{ if eq .machine "gentoo-workstation" -}}
# Workstation-only config
{{- end }}

# Apply and commit
chezmoi apply
chezmoi cd && git add . && git commit -m "feat: add workstation config" && git push

Pattern 4: Temporarily Disable Chezmoi

# Edit file directly (bypassing chezmoi)
nvim ~/.zshrc

# Test changes
source ~/.zshrc

# If good, update chezmoi
chezmoi add ~/.zshrc
chezmoi cd && git add . && git commit -m "feat: update zshrc" && git push

Best Practices

  1. Always preview before applying

    chezmoi diff  # Check what will change
    chezmoi apply # Then apply
    
  2. Test changes before committing

    chezmoi apply
    # Test the changes
    # If broken, fix and re-apply
    # Only commit when working
    
  3. Use templates for cross-platform configs

    • OS-specific paths
    • Package manager commands
    • Tool locations
  4. Keep commits atomic and descriptive

    # Good
    git commit -m "feat: add starship prompt configuration"
    
    # Bad
    git commit -m "update stuff"
    
  5. Document complex templates

    # Add comments in templates
    # {{ if eq .chezmoi.os "darwin" -}}
    # macOS uses Homebrew in /opt/homebrew
    export PATH="/opt/homebrew/bin:$PATH"
    # {{- end }}
    
  6. Don't commit secrets

    • Use .chezmoiignore for sensitive files
    • Or use encryption for files that must be synced
  7. Test on a VM before deploying widely

    • Especially for major changes
    • Prevents breaking all machines at once

Resources


Summary

Daily workflow:

  1. chezmoi edit ~/.config - Edit configs
  2. chezmoi diff - Preview changes
  3. chezmoi apply - Apply changes
  4. chezmoi cd && git add . && git commit && git push - Commit
  5. chezmoi update on other machines - Sync

Adding new tools:

  1. Install and configure the tool
  2. chezmoi add ~/.config/tool - Add to chezmoi
  3. Commit and push

Cross-platform:

  1. chezmoi chattr +template ~/.file - Make template
  2. Add {{ if eq .chezmoi.os "..." }} logic
  3. Apply and test on each platform

Your dotfiles are now version controlled, synced across machines, and managed professionally!