My personal dotfiles management operation notes. The official chezmoi docs are sufficient, so here I'll write only about how it actually runs in my own environment.
Prerequisite environment
| Item | Value |
|---|---|
| Source directory | ~/.local/share/chezmoi/ |
| Remote | https://github.com/mizchi/chezmoi-dotfiles.git |
| Branch | main |
| pre-commit | prek + secretlint |
| post-apply hook | run_after_apm-install.sh → apm install --global --target claude |
Layout quick reference
~/.local/share/chezmoi/
├── dot_apm/ → ~/.apm/ (APM config)
├── dot_claude/ → ~/.claude/ (Claude Code)
│ ├── CLAUDE.md.tmpl
│ ├── settings.json.tmpl
│ ├── rules/
│ └── skills/ → ~/.claude/skills/ (自作スキル)
├── dot_codex/ → ~/.codex/
├── dot_config/ → ~/.config/ (helix, mise, sheldon, starship, zellij, zsh)
├── dot_zshrc → ~/.zshrc
└── run_after_apm-install.sh (scripts/run_after_* は apply 後に毎回実行される)
Meaning of filename prefixes
| prefix | Meaning | Example |
|---|---|---|
dot_ |
Leading . |
dot_zshrc → .zshrc |
executable_ |
+x permission |
executable_setup.sh → setup.sh (755) |
private_ |
0600 permission |
private_key → key (600) |
.tmpl |
Go template | CLAUDE.md.tmpl → expanded by hostname etc. into CLAUDE.md |
run_once_ |
Run only on first time | run_once_install_brew.sh |
run_after_ |
Run every time after apply | run_after_apm-install.sh |
Daily flow
① See what differs
chezmoi diff # source と dest の差分
chezmoi status # 大雑把な状態(MM/M /?? など)
chezmoi diff sense of direction: output is in the order - dest / + target (following the git diff convention of old=current / new=after apply).
-lines = content in dest (the current actual file) — will be by apply+lines = content in target (the expected state after source.tmpl expansion) — will be by applychezmoi applyis the direction of making dest match target (source → dest)
If confused, it's fastest to look at both cat <source> と cat <dest> and confirm.
chezmoi status column is [source][dest]:
M= modified,A= added,D= deleted,?= untracked (not in source)MM→ both changed (manually edited dest needs to be taken into source)M→ source hasn't changed but only dest was changed (stray change)DA→ treated as deleted in source but exists in dest (junk such asnode_modules/)
② Edited dest (the actual file) → take it into source
chezmoi add ~/.zshrc # 新規ファイル追加
chezmoi re-add # managed な dest の変更を一括で source に反映
chezmoi re-add ~/.claude/CLAUDE.md # 個別
③ Edited source (the repository side) → reflect it in dest
chezmoi diff # 先に見る
chezmoi apply # 全体
chezmoi apply ~/.claude/CLAUDE.md # 個別
chezmoi apply --verbose # 何をやってるか表示
④ Open source in an editor
chezmoi edit ~/.zshrc # source 側を開く (エディタ閉じた後に apply する?は -a フラグ)
chezmoi edit -a ~/.zshrc # 編集後 apply も実行
chezmoi cd # source dir に cd
New machine initialization
# chezmoi 本体: brew install chezmoi など
chezmoi init https://github.com/mizchi/chezmoi-dotfiles.git --apply
# ↑ clone + apply までやる。run_after_apm-install.sh が走って
# apm install --global --target claude で外部スキルが入る
# pre-commit 有効化(新マシンで一度だけ)
cd $(chezmoi source-path)
prek install
Skill addition flow (my own standard routine)
~/.claude/skills/<name>/to develop and verify operation (in the case of nix-setup, go through up tonix build)chezmoi add ~/.claude/skills/<name>to reflect it in source+xscripts with the attribute automatically get theexecutable_prefix
cd ~/.local/share/chezmoi && git statusto check the added filesgit add dot_claude/skills/<name>/+ commit +git push origin main
When editing an existing skill
chezmoi add even with chezmoi re-add will also be overwritten. Usually re-add produces fewer unnecessary diffs:
chezmoi re-add ~/.claude/skills/nix-setup/SKILL.md
Boundary between APM and chezmoi
~/.claude/skills/ は Two systems coexist:
| Type | How it gets in | Managed location |
|---|---|---|
| APM-managed (external repo) | apm install --global fetched after apply |
~/.local/share/chezmoi/dot_apm/apm.yml |
| chezmoi-managed (self-made) | chezmoi add copy to source with |
~/.local/share/chezmoi/dot_claude/skills/<name>/ |
What is currently installed via APM (dot_apm/apm.yml excerpt):
moonbitlang/moonbit-agent-guide/*(moonbit-agent-guide, moonbit-refactoring, moonbit-c-binding)mizchi/moonbit-practice/skills/moonbit-practicemizchi/flaker/skills/flaker-setupast-grep/agent-skill/ast-grepmizchi/tui.mbt/skills/tuimbt-practice
Criteria for judgment:
- Externally public / likely to be used from other repositories → put it in an upstream repo and register it with APM
- Operational notes used only in my own environment / skills under experimentation → chezmoi management
If directories with the same name exist in both locations, APM may overwrite during install, so be careful about name collisions.
Before adding a new skill to chezmoi, check for name collisions with APM:
# APM 側に同名がないか確認
grep "<skill-name>" ~/.local/share/chezmoi/dot_apm/apm.yml
# or
chezmoi cd && grep -r "<skill-name>" dot_apm/
Editing tmpl files
CLAUDE.md.tmpl や settings.json.tmpl は Go template:
chezmoi edit ~/.claude/CLAUDE.md # 実体ではなく source の .tmpl が開く
chezmoi execute-template < foo.tmpl # 手動で展開結果を確認
chezmoi data # 展開で使えるデータを一覧(ホスト名、OS 等)
Example template variables: {{ .chezmoi.os }}, {{ .chezmoi.hostname }}
Caution: .tmpl For managed files (CLAUDE.md.tmpl, settings.json.tmpl etc.), running chezmoi re-add will overwrite the source's .tmpl syntax with the expanded dest content..tmpl If you want to update a chezmoi editfile, use .tmpl (which automatically opens the~/.local/share/chezmoi/dot_claude/CLAUDE.md.tmpl directly.
Pre-check before re-add: Always verify with .tmpl whether the target file is managed by chezmoi source-path :
chezmoi source-path ~/.claude/CLAUDE.md
# → /Users/mz/.local/share/chezmoi/dot_claude/CLAUDE.md.tmpl
# 末尾 .tmpl なら re-add せず手動編集。.tmpl でなければ re-add OK
When you want to change the default value of a tmpl variable
Rather than rewriting the tmpl itself to be hardcoded,~/.config/chezmoi/chezmoi.toml の [data] section:
[data]
claude_default_mode = "auto"
github_username = "mizchi"
{{ .claude_default_mode | default "acceptEdits" }} Keep the tmpl structure like [data] for more flexibility (leaving room to change settings between machines).
pre-commit (prek + secretlint)
Before committing, prek runs via secretlint , and diffs containing API keys or tokens are rejected.
Common false positives:
- Example sha256 / hex strings (may be flagged if the length resembles an aws key / github token)
.envrcSample values written in comments in
Workaround:
# 本当に誤検出なら .secretlintrc.json でルールを除外
# 検出が正しいなら該当行を修正して git add ... && git commit
.secretlintrc.json (excerpt):
{
"rules": [
{
"id": "@secretlint/secretlint-rule-preset-recommend",
"options": {
"allows": [
"/sha256-[a-f0-9]{64}/",
"fake-token-for-example",
"skill-examples/*"
]
}
}
]
}
allows is a regular expression (enclosed in/.../ ) or a string match. Per-file exclusion is possible with disabledRules + includes/excludes .
--no-verify (it becomes meaningless).
Troubleshooting
chezmoi status に DA appears in large numbers (node_modules/ etc.)
.chezmoiignore :
node_modules
**/.DS_Store
source and dest are conflicting
chezmoi merge ~/.zshrc # 3-way merge (vimdiff 系)
chezmoi forget ~/.something # source から削除(dest は残す)
chezmoi destroy ~/.something # 両方削除(破壊的)
chezmoi merge backend of ~/.config/chezmoi/chezmoi.toml の [merge] section:
[merge]
command = "nvim"
args = ["-d", "{{ .Destination }}", "{{ .Source }}", "{{ .Target }}"]
When unset, refer to git config merge.tool . If neither is set, fall back to vimdiff.
apply broke something → revert to the previous revision
chezmoi itself has no undo. Revert with git on the source side:
chezmoi cd
git log --oneline -5
git reset --hard <rev>
cd -
chezmoi apply
which files are managed
chezmoi managed # 管理対象ファイルの一覧
chezmoi unmanaged ~/ # 未管理ファイル
chezmoi managed ~/.claude # パス絞り込み
apply is slow
run_after_apm-install.sh の apm install is running every time. If there are no skill updates, skip it at apply time with an environment variable:
SKIP_APM=1 chezmoi apply # スクリプト側が対応している場合のみ(未対応なら無視)
If unsupported, ignore.
Reference command quick guide
chezmoi diff # 差分
chezmoi status # 状態
chezmoi apply [-v] # 適用
chezmoi add <path> # 新規取り込み
chezmoi re-add [<path>] # 既存の取り込み直し
chezmoi edit [-a] <path> # source を編集 (-a で直後に apply)
chezmoi merge <path> # 競合の 3-way merge
chezmoi forget <path> # source から外す
chezmoi managed [<path>] # 管理対象一覧
chezmoi unmanaged <path> # 未管理ファイル
chezmoi cd # source-path に cd
chezmoi source-path # source ディレクトリ表示
chezmoi execute-template < # テンプレ展開テスト
chezmoi data # テンプレで使える変数一覧
chezmoi doctor # セットアップ診断