mcpField
C
chezmoi-management

chezmoi-management

github.com/mizchi开发41665 次安装1 周前更新
代码仓库

关于 chezmoi-management

面向维护 mizchi 个人配置的 chezmoi 操作指南,说明与 Nix home-manager、APM 的职责边界,并涵盖日常同步、初始化和故障处理。

主要功能

  1. 01对照 source 与目标文件检查差异
  2. 02在配置源与目标间同步文件
  3. 03使用 Go 模板管理配置
  4. 04区分 home-manager、chezmoi 与 APM 管理范围
  5. 05通过推送钩子运行密钥扫描

适用场景

  1. 01在新机器上初始化个人配置环境
  2. 02将手动修改的配置纳入 chezmoi
  3. 03排查 apply 后的配置冲突
  4. 04避免 APM 技能与 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-pushpkfire(Taskfile.pkl + pkf hooks install)+ secretlint
应用后钩子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 派生构建安装的工具(例如 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.* 封装器,就在那里进行配置,不要再通过 chezmoi 暂存对应的 dotfile。混用会导致两个事实来源相互冲突,表现为“我编辑了文件,但更改总是被还原”。

目录布局速查

~/.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)
.tmplGo 模板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 前缀由 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

技能添加流程(我的个人惯例)

  1. 在 ~/.claude/skills/<name>/ 中开发并验证(对于 nix-setup,需确保 nix build 通过)
  2. 运行 chezmoi add ~/.claude/skills/<name>,将其同步到源目录
    • 带有 +x 的脚本会自动添加 executable_ 前缀
  3. 运行 cd ~/.local/share/chezmoi && git status,确认已添加的文件
  4. 运行 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/ 是两个系统的混合目录:

类型添加方式管理位置
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-practice
  • mizchi/flaker/skills/flaker-setup
  • ast-grep/agent-skill/ast-grep
  • mizchi/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。

重新添加前的检查:始终使用 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/十六进制字符串(长度可能类似 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。

Apply 弄坏了东西 → 回滚到之前的修订版本

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 每次都会运行。如果不需要更新 skill,可在 apply 时通过环境变量跳过:

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

评论

支持 Markdown