chezmoi-management について
mizchi の個人用 dotfiles を管理するための chezmoi 運用ガイドです。Nix home-manager や APM との役割分担、日々の同期、新しいマシンの初期設定、トラブル対応を説明します。
主な機能
- 01ソースと配置先の差分確認
- 02ソースと配置先のファイル同期
- 03Go テンプレートによる設定管理
- 04home-manager、chezmoi、APM の管理範囲の整理
- 05pre-push フックによるシークレット検査
活用シーン
- 01新しいマシンで dotfiles 環境を構築
- 02手動編集した設定を chezmoi に反映
- 03apply 後の設定競合を調査
- 04APM のスキルと chezmoi のファイルの衝突を防止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mizchi/ skills --skill chezmoi-managementインストール後、Claude Code で/chezmoi-managementを入力して読み込まれたか確認します。
同梱ファイルREADME.mdSKILL-ja.md
詳細
chezmoi の管理(mizchi 個人用)
個人用 dotfiles の運用メモです。chezmoi の公式ドキュメントで十分に説明されているため、このドキュメントでは自分の環境で具体的にどのように動作するかだけを扱います。
基本環境
| 項目 | 値 |
|---|---|
| ソースディレクトリ | ~/.local/share/chezmoi/ |
| リモート | https://github.com/mizchi/chezmoi-dotfiles.git |
| ブランチ | main |
パッケージ / programs.* | dot_config/home-manager/flake.nix 経由の nix home-manager(単独の home-manager、または nix-darwin 統合モード) |
| pre-push | pkfire(Taskfile.pkl + pkf hooks install)+ secretlint |
| apply 後のフック | run_after_apm-install.sh → apm install --global --target claude |
nix home-manager との役割分担
このリポジトリは home-manager と併用します。一方が他方の機能をすべて包含するわけではありません。
- home-manager が管理するもの:CLI パッケージ(
home.packages)、programs.*ラッパー(git / direnv / zsh など)、および Nix の derivation を介してインストールされるツール(例:pkfire、pkl、actionlint、awscli2、pkgs.go)。dot_config/home-manager/common.nixを編集し、darwin-rebuild switch --flake .#macos(またはhome-manager switch)を実行します。 - chezmoi が管理するもの:
programs.*では形を整えられない dotfile の内容、つまり~/.claude/、~/.codex/、~/.apm/、任意の~/.config/<editor-or-shell>/、~/.zshrc、テンプレートとして保持するパスです。 - APM が管理するもの:
~/.claude/skills/<name>/以下の公開 Claude Code スキルです。.chezmoiignoreには APM が管理する各スキルが記載されているため、chezmoi がapm install -gによる配置を上書きすることはありません。
ルール:あるツールに対して home-manager に programs.* ラッパーがある場合は、そこで設定してください。その dotfile も chezmoi 経由で管理しないでください。併用すると、2つの情報源が競合し、「ファイルを編集したのに変更が元に戻り続ける」という問題が発生します。
レイアウト早見表
~/.local/share/chezmoi/
├── dot_apm/ → ~/.apm/ (APM config)
├── dot_claude/ → ~/.claude/ (Claude Code)
│ ├── CLAUDE.md.tmpl
│ ├── settings.json.tmpl
│ ├── rules/
│ └── skills/ → ~/.claude/skills/ (self-authored skills)
├── dot_codex/ → ~/.codex/
├── dot_config/ → ~/.config/ (helix, mise, sheldon, starship, zellij, zsh, home-manager)
│ └── home-manager/ → ~/.config/home-manager/ (flake.nix / common.nix / darwin.nix — Nix-evaluated; chezmoi only stages the files, Nix does the actual install)
├── dot_zshrc → ~/.zshrc
├── run_once_before_install-brew.sh (bootstrap: clone Homebrew prefix to ~/brew before nix-darwin first activation)
└── run_after_apm-install.sh (every apply: apm install --global --target claude)
ファイル名の接頭辞の意味
| 接頭辞 | 意味 | 例 |
|---|---|---|
dot_ | 先頭に . を付ける | dot_zshrc → .zshrc |
executable_ | +x 権限 | executable_setup.sh → setup.sh(755) |
private_ | 0600 権限 | private_key → key(600) |
.tmpl | Go テンプレート | CLAUDE.md.tmpl → ホスト名などを展開した CLAUDE.md |
run_once_ | 初回のみ実行 | run_once_install_brew.sh |
run_after_ | apply のたびに実行 | run_after_apm-install.sh |
日々の作業の流れ
(1)差分を確認する
chezmoi diff # diff between source and dest
chezmoi status # rough status (MM/M /?? etc.)
chezmoi diff の方向:出力は - dest / + target の順です(git diff の「旧状態=現在」/「新状態=apply 後」という規則に従います)。
-の行 = dest(現在の実ファイル)の内容 — apply によって削除されます+の行 = target(source.tmpl の展開後に期待される状態)の内容 — apply によって追加されますchezmoi applyは dest を target に合わせる方向に変更します(source → dest)
迷った場合は、cat <source> と cat <dest> の両方を確認するのが最も手早い方法です。
chezmoi status の列は [source][dest] です。
M= 変更あり、A= 追加、D= 削除、?= 未追跡(source にない)MM→ 両側に変更あり(手動で編集した dest を source に取り込む必要があります)M→ source は変更なし、dest は変更あり(想定外の変更)DA→ source では削除済みの扱いですが、dest には存在します(node_modules/などの不要ファイル)
(2)dest(実ファイル)を編集 → source に取り込む
chezmoi add ~/.zshrc # add a new file
chezmoi re-add # bulk-reflect changes from managed dest into source
chezmoi re-add ~/.claude/CLAUDE.md # individual
(3)source(リポジトリ側)を編集 → dest に反映する
chezmoi diff # look first
chezmoi apply # all
chezmoi apply ~/.claude/CLAUDE.md # individual
chezmoi apply --verbose # show what it's doing
(4)エディターで source を開く
chezmoi edit ~/.zshrc # open the source side (whether to apply after closing the editor is controlled by the -a flag)
chezmoi edit -a ~/.zshrc # also run apply after editing
chezmoi cd # cd to source dir
新しいマシンの初期設定
インストール順は nix → chezmoi → apm です。brew の prefix は chezmoi の run_once_before_install-brew.sh によって初期設定されるため、初回の有効化時に nix-darwin の homebrew モジュールから ~/brew を参照できます。
# 1. Install Nix (Determinate Systems installer recommended).
curl -fsSL https://install.determinate.systems/nix | sh -s -- install
# 2. Bootstrap chezmoi (clones repo + applies; the brew script runs once here).
chezmoi init https://github.com/mizchi/chezmoi-dotfiles.git --apply
# 3. Switch home-manager / nix-darwin (installs pkfire, pkl, awscli2, …).
nix run nix-darwin -- switch --flake ~/.config/home-manager#macos
# (or for standalone HM without system-layer changes:
# nix run home-manager/master -- switch --flake ~/.config/home-manager#macos)
# 4. Arm the pre-push gate on this repo's source.
cd $(chezmoi source-path)
pkf hooks install # writes .git/hooks/pre-push (secretlint over outgoing diff)
# 5. apm install -g already fired via run_after_apm-install.sh during step 2.
# To pick up upstream updates later: apm install -g --update
スキル追加の手順(個人的なルーチン)
~/.claude/skills/<name>/で開発・検証します(nix-setup の場合は、nix buildが成功することを確認します)chezmoi add ~/.claude/skills/<name>でソースに反映します+xが付いたスクリプトには、自動的にexecutable_プレフィックスが付きます
cd ~/.local/share/chezmoi && git statusで追加されたファイルを確認しますgit add dot_claude/skills/<name>/を実行し、コミットしてgit push origin mainでプッシュします
既存のスキルを編集した場合
chezmoi add と chezmoi re-add はどちらも上書きします。実際には、re-add のほうが不要な差分が少なくなる傾向があります。
chezmoi re-add ~/.claude/skills/nix-setup/SKILL.md
APM と chezmoi の境界
~/.claude/skills/ は、2つのシステムが混在しています。
| 種類 | 追加方法 | 管理場所 |
|---|---|---|
| APM 管理(外部リポジトリ) | apply 後に apm install --global で取得 | ~/.local/share/chezmoi/dot_apm/apm.yml |
| chezmoi 管理(自作) | chezmoi add でソースにコピー | ~/.local/share/chezmoi/dot_claude/skills/<name>/ |
現在 APM 経由でインストールされているもの(dot_apm/apm.yml から抜粋):
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
判断基準:
- 公開されている、または他のリポジトリでも使う可能性が高いもの → 上流リポジトリに置き、APM に登録します
- 自分の環境でのみ使う運用メモや実験的なスキル → chezmoi で管理します
同じ名前のディレクトリが両方の場所に存在する場合、インストール時に APM が上書きする可能性があるため、名前の衝突に注意してください。
chezmoi に新しいスキルを追加する前に、APM との名前の衝突を確認します:
# Check whether the same name exists on the APM side
grep "<skill-name>" ~/.local/share/chezmoi/dot_apm/apm.yml
# or
chezmoi cd && grep -r "<skill-name>" dot_apm/
tmpl ファイルの編集
CLAUDE.md.tmpl と settings.json.tmpl は Go テンプレートです。
chezmoi edit ~/.claude/CLAUDE.md # opens the source-side .tmpl, not the real file
chezmoi execute-template < foo.tmpl # manually check the expansion result
chezmoi data # list data available for expansion (hostname, OS, etc.)
テンプレート変数の例:{{ .chezmoi.os }}、{{ .chezmoi.hostname }}
注意:.tmpl で管理されているファイル(CLAUDE.md.tmpl、settings.json.tmpl など)に対して chezmoi re-add を実行すると、ソース内の .tmpl 構文が展開済みの配信先コンテンツで上書きされます。.tmpl ファイルを更新するには、chezmoi edit(.tmpl 側が自動的に開きます)を使うか、~/.local/share/chezmoi/dot_claude/CLAUDE.md.tmpl を直接編集してください。
re-add の前に確認:chezmoi source-path を使って、対象ファイルが .tmpl で管理されているか必ず確認してください。
chezmoi source-path ~/.claude/CLAUDE.md
# → /Users/mz/.local/share/chezmoi/dot_claude/CLAUDE.md.tmpl
# If it ends in .tmpl, don't re-add — edit manually. If not .tmpl, re-add is OK
tmpl 変数のデフォルト値を変更する場合
tmpl 自体を固定値に書き換えるのではなく、変数を ~/.config/chezmoi/chezmoi.toml の [data] セクションに設定してください。
[data]
claude_default_mode = "auto"
github_username = "mizchi"
{{ .claude_default_mode | default "acceptEdits" }} のような tmpl 構造はそのまま残し、ホストごとに [data] で値だけを切り替えるほうが柔軟です(マシンごとに設定を変えられます)。
pre-push(pkfire + secretlint)
secretlint は pkfire を介して git push 時に実行されます(Taskfile.pkl → pkf hooks install → .git/hooks/pre-push)。これからプッシュする差分の範囲が対象です。API キーやトークンを含む差分は拒否されます。
新しいチェックアウトでフックを再設定するには、pkf hooks install を実行してください。緊急時の回避方法:git push --no-verify。
よくある誤検知:
- sha256 の例や 16 進数文字列(長さが AWS キーや GitHub トークンに似ていると検出されることがあります)
.envrcのコメントに記載されたサンプル値
対処方法:
# If it really is a false positive, exclude the rule in .secretlintrc.json
# If the detection is correct, fix the line and git add ... && git commit
.secretlintrc.json での除外構文(抜粋):
{
"rules": [
{
"id": "@secretlint/secretlint-rule-preset-recommend",
"options": {
"allows": [
"/sha256-[a-f0-9]{64}/",
"fake-token-for-example",
"skill-examples/*"
]
}
}
]
}
allows には、正規表現(/.../ で囲みます)またはリテラル文字列を指定します。disabledRules と includes/excludes を使って、ファイル単位で除外することもできます。
--no-verify は使わないでください(目的が損なわれます)。
トラブルシューティング
chezmoi status に大量の DA(node_modules/ など)が表示される
.chezmoiignore に追記します:
node_modules
**/.DS_Store
ソースと配信先が競合する
chezmoi merge ~/.zshrc # 3-way merge (vimdiff-style)
chezmoi forget ~/.something # remove from source (keep dest)
chezmoi destroy ~/.something # remove both (destructive)
chezmoi merge のバックエンドは、~/.config/chezmoi/chezmoi.toml の [merge] セクションで設定します。
[merge]
command = "nvim"
args = ["-d", "{{ .Destination }}", "{{ .Source }}", "{{ .Target }}"]
設定されていない場合、chezmoi は git config merge.tool を参照します。どちらも設定されていない場合は、vimdiff にフォールバックします。
適用で問題が発生した → 以前のリビジョンにロールバックする
chezmoi 自体には取り消し機能がありません。ソース側で git を使ってロールバックしてください:
chezmoi cd
git log --oneline -5
git reset --hard <rev>
cd -
chezmoi apply
管理対象のファイル
chezmoi managed # list of managed files
chezmoi unmanaged ~/ # unmanaged files
chezmoi managed ~/.claude # filter by path
apply が遅い
run_after_apm-install.sh 内の apm install は毎回実行されます。スキルの更新が不要な場合は、適用時に環境変数を使ってスキップしてください:
SKIP_APM=1 chezmoi apply # only if the script supports it (otherwise ignored)
サポートされていない場合は、無視してください。
リファレンス:コマンド早見表
chezmoi diff # diff
chezmoi status # status
chezmoi apply [-v] # apply
chezmoi add <path> # take in a new file
chezmoi re-add [<path>] # re-take an existing file
chezmoi edit [-a] <path> # edit source (-a applies immediately after)
chezmoi merge <path> # 3-way merge for conflicts
chezmoi forget <path> # drop from source
chezmoi managed [<path>] # list managed files
chezmoi unmanaged <path> # unmanaged files
chezmoi cd # cd to source-path
chezmoi source-path # show source directory
chezmoi execute-template < # test template expansion
chezmoi data # list variables usable in templates
chezmoi doctor # setup diagnosis