chezmoi

chezmoi 把 dotfiles 收进一个 git 仓库,在每台机器上 apply 出去,还能按系统做模板差异。用法网上一大把,我这儿真正想说的是边界:⁠什么该交给它管,什么不该。

我的标准是"自己手写、要多机一致"的才进。对应到现在,纳管的就是跨平台那几样:WezTerm 的 ~/.wezterm.lua、Windows 上的 Neovim 配置、Windows 的 PowerShell profile 和 AutoHotKey。这几样我会两台机器来回改,一致性有价值。

反过来,Linux 桌面那一大坨——Hyprland、Quickshell、waybar——我没塞进来。一是体量大(光 Quickshell 就七万行),二是它跟着上游 rice 更新,我宁可"跟上游 + 本地改几处",也不想把别人的几万行 QML 纳进自己的 dotfiles 仓库当包袱。还有含密钥的东西也一律不进——那种该走环境变量或单独 gitignore,别让它进任何仓库历史。

留下的日常很简单:

chezmoi edit ~/.wezterm.lua    # 改源
chezmoi diff                   # 看 apply 会动什么
chezmoi apply                  # 落地
chezmoi cd && git commit -a && git push

新机器一句 chezmoi init --apply <repo> 拉下来铺好。

它的两块机制值得知道,够用就行:

文件名前缀即属性⁠——chezmoi 不存元数据,把属性编码进源文件名:dot_foo~/.fooprivate_ → 权限 600、executable_ → 加可执行位、readonly_encrypted_(配合 age/gpg 落地时解密)、run_ 开头的脚本会在 apply 时执行(run_once_ 只跑一次,适合装包/初始化)。看一眼文件名就知道它会变成什么。

模板做按机差异⁠——*.tmpl 走 Go template,能读 .chezmoi.os.chezmoi.hostname 这些内置变量和你自己在 .chezmoidata / config 里定义的值:

{{ if eq .chezmoi.os "windows" }}
shell = "pwsh"
{{ else }}
shell = "zsh"
{{ end }}

同一份源,在 Windows 和 Linux apply 出不同结果——这正是我那几样跨平台配置(WezTerm、PowerShell、Windows 上的 Neovim)能共用一份的原因。chezmoi diff 在 apply 前永远先让我看清模板渲染后到底会写什么。

够用,不复杂——复杂的地方从来不在工具,在"克制别什么都往里塞"。