Migration
Migrating from a bare git repo
The git --git-dir=$HOME/.dotfiles --work-tree=$HOME pattern, usually behind a config alias. No dependencies, no symlinks, no templating — and $HOME is the work tree, which is the part that has to change.
Concept mapping
| Bare repo | Here |
|---|---|
config add ~/.bashrc | dot add ~/.bashrc |
config commit / config push | ordinary git inside $(dot cd) |
config status | dot status |
config checkout on a new machine | dot init <user> |
.gitignore with * at $HOME | not needed — $HOME is not a work tree |
showUntrackedFiles = no | not needed, same reason |
| Per-host: branches | .tmpl files with {{ if }} |
| Nothing | dot doctor, dot heal, dot rollback, secrets, provisioning |
1. Inventory and back up
Push first if the repo has a remote — the safest rollback is a clone:
2. Note your branch layout
Per-host branches are the one thing that needs a design decision. List them before you start:
|
Every branch becomes conditional blocks in one file. Diff two branches now, while the context is fresh:
3. Install
The bare repo is at $HOME/.dotfiles, which is also this project's default clone location. The installer detects and refuses to clobber it, but move it first to avoid the confusion entirely:
# Download and verify the release installer per docs/guides/INSTALL.md first.
Your files in $HOME are untouched by the move — only the git metadata directory changed name.
4. Import
while ; do
[ &&
done
5. Collapse branches into templates
Take the differences you diffed in step 2 and express them as conditions in a single .tmpl:
export EDITOR=nvim
{{ if eq .chezmoi.hostname "work-laptop" }}
export HTTP_PROXY=http://proxy.corp:3128
export NPM_CONFIG_REGISTRY=https://nexus.corp/repository/npm/
{{ end }}
{{ if eq .chezmoi.os "darwin" }}
export HOMEBREW_NO_ANALYTICS=1
{{ end }}
Rendering is testable without applying:
6. Apply and verify
while ; do
[ ||
done
7. Clean up
# Only if you had the $HOME/.gitignore containing '*' trick:
&&
# Remove the alias from your shell rc, then, once confident:
Do not remove the backup until you have pushed the new source tree somewhere and used it for a while.
Rolling back
Or, if you pushed in step 1, clone the remote bare again — which is why step 1 says to push.
What you gain, what you lose
Gain: templating instead of branch-per-host (the bare-repo pattern's real weakness: merging a change across five host branches); a CLI with diagnostics and repair; secrets; provisioning hooks; multi-shell parity; signed releases.
Lose: zero dependencies. The bare-repo trick needs nothing but git, and that is a genuine virtue — especially on a locked-down host. You also lose $HOME as a work tree, so git status there no longer tells you what changed; dot status does. And the setup no longer fits in a three-line shell alias you can retype from memory.