Dotfile Management: chezmoi, GNU Stow, Bare Git Repos


Introduction





Dotfiles — configuration files for your shell, editor, git, and other tools — are the backbone of your development environment. Properly managing them ensures consistency across machines, easy recovery after a crash, and collaboration with your team. This article compares the three main approaches: chezmoi, GNU Stow, and bare git repositories.





Bare Git Repo





The simplest approach: use git directly without any additional tool:






# Initialize a bare repository in your home directory


git init --bare $HOME/.dotfiles




# Create an alias to manage it


alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME'




# Add the alias to your shell config


echo "alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME'" >> ~/.zshrc




# Start tracking files


dotfiles status


dotfiles add ~/.zshrc ~/.gitconfig ~/.tmux.conf


dotfiles commit -m "Initial dotfiles"


dotfiles remote add origin git@github.com:user/dotfiles.git


dotfiles push -u origin main




# On a new machine:


git clone --bare https://github.com/user/dotfiles.git $HOME/.dotfiles


alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME'


dotfiles checkout







**Pros**: No external dependencies, just git. Simple to understand.


**Cons**: No templating (machine-specific configs require symlink hacks). Lacks encryption for secrets. Easy to accidentally commit sensitive data.





GNU Stow





Stow creates symlinks from a structured directory to your home directory:






# Directory structure


~/dotfiles/


zsh/


.zshrc


.zprofile


git/


.gitconfig


.gitignore_global


tmux/


.tmux.conf


nvim/


.config/nvim/


init.lua




# Install all packages


stow -t $HOME zsh git tmux nvim




# Stow creates symlinks:


# ~/dotfiles/zsh/.zshrc -> ~/.zshrc


# ~/dotfiles/git/.gitconfig -> ~/.gitconfig




# Uninstall a package


stow -D -t $HOME zsh




# Restow (update symlinks after changes)


stow -R -t $HOME nvim







**Pros**: Clean directory structure. Easy to understand. Works on any Unix system.


**Cons**: No templating. No encryption. Conflicts if files overlap. Root privileges needed for system configs.





chezmoi





chezmoi is purpose-built for dotfile management with advanced features:






# Install chezmoi


sh -c "$(curl -fsLS get.chezmoi.io)"




# Initialize


chezmoi init




# Add a file


chezmoi add ~/.zshrc


chezmoi add ~/.config/nvim/init.lua




# Edit a tracked file


chezmoi edit ~/.zshrc




# See what would change


chezmoi diff




# Apply changes


chezmoi apply




# On a new machine


chezmoi init https://github.com/user/dotfiles.git


chezmoi apply







Templating with chezmoi





chezmoi supports Go templates for machine-specific configs:






# .zshrc.tmpl — template file


export EDITOR='{{ if eq .chezmoi.os "darwin" }}code{{ else }}nvim{{ end }}'




{{ if eq .chezmoi.hostname "work-laptop" }}


export WORK_MODE=true


export AWS_PROFILE=work


{{ end }}




# Template data includes: OS, hostname, architecture, username, and custom variables







Secret Management






# Store secrets in your password manager


chezmoi secret set github_token


chezmoi secret set ssh_private_key




# Use in templates


{{ (secret "github_token") | quote }}




# Or use encrypted files with age/gpg


chezmoi age encrypt ~/.ssh/id_ed25519 > ~/.local/share/chezmoi/encrypted_dot_ssh/id_ed25519.age







Comparison





| Feature | Bare Git | GNU Stow | chezmoi |


|---------|----------|----------|---------|


| Dependencies | Git only | Stow + Git | chezmoi binary |


| Templating | No | No | Full Go templates |


| Secret management | Manual encryption | Manual encryption | Built-in (age/gpg/password managers) |


| Learning curve | Low | Low | Medium |


| Cross-platform | Yes | Unix only | Yes |


| Dry-run preview | `git diff` | N/A | `chezmoi diff` |


| Scriptability | Git commands | Shell scripts | `chezmoi apply` |


| Community size | Very large | Large | Growing |





Recommendations




* **Single machine, no secrets**: Bare git repo is the simplest approach.

* **Multiple Unix machines**: GNU Stow provides clean structure with minimal dependencies.

* **Multiple machines with different configs**: chezmei's templating handles this elegantly.

* **Need secret management**: chezmoi's built-in encryption and password manager integration is essential.

* **Team dotfiles**: chezmoi's robust apply/diff workflow supports collaboration safely.




Choose chezmoi if you have more than two machines or need secret management. Choose bare git for simplicity on single-machine setups. Choose Stow if you prefer Unix philosophy and have mostly identical machines.