devAlice
← Mac

Dotfiles 管理 — chezmoi vs yadm vs 原始符号链接,Mac 版

对比跨机器干净复现同一开发环境的几种工具,并提供 chezmoi 的实战配置步骤。

如果你每次换 Mac 还在手动复制粘贴 .zshrc.gitconfig~/.config/...,是时候使用 dotfiles 管理工具了。一次配置,新机器一条命令即可完整恢复所有配置。

我认为 dotfiles 管理最重要的不是工具选择,而是建立单一真实来源的纪律。以前配置散落在各台机器上;如今通过 chezmoi 的 Git 化管理,任何机器的配置漂移都变得可见,因为版本控制才是配置一致性的保障。

本指南对比三种方案(chezmoi · yadm · 原始符号链接 + Git),并详细讲解推荐的 chezmoi 配置流程。

TL;DR

工具优势劣势适用场景
chezmoi(推荐)模板 / 按机器分支 / 密钥集成 / 双向应用学习曲线(Go 模板)1 台以上机器,混合 OS
yadmGit 封装,零学习成本按机器分支较弱简单单 OS 场景
原始符号链接 + Git零依赖,透明一切自己来极简主义者

1. 为什么需要 Dotfiles 工具

.zshrc 直接放进 Git 仓库并创建符号链接是可行的,但这些问题会逐渐积累:

  • 按机器差异:工作 Mac 的 git user.email vs 个人 Mac — 最终硬编码分支难以维护。
  • 密钥管理:API 密钥 / SSH 配置混在其中很危险,容易忘记写 .gitignore
  • 双向同步:如果直接编辑 ~/.zshrc,仓库就会漂移,分不清哪个才是真实来源。
  • 新机器恢复:clone → 安装依赖 → 创建符号链接 → 调整权限……每次都要重复一遍。

Dotfiles 工具将这些整合为一致的工作流。

2. 方案对比

chezmoi

基于 Go 的 CLI。模板引擎(按机器分支)、密钥管理(1Password / Bitwarden 集成)、双向同步(chezmoi diff / chezmoi apply)。

yadm

~ 中的 dotfiles 作为直接 Git 仓库的 Git 封装工具。零学习成本。按机器分支支持有限(通过 .zshrc##os.Darwin 等 alt 文件实现)。

原始符号链接 + Git

将文件放在 ~/dotfiles/ 并用安装脚本创建符号链接。最透明,但所有功能都需要自己实现。

推荐:chezmoi

对于拥有 1-3 台机器的个人开发者,chezmoi 毫无疑问是最佳选择。一小时的学习投入,终身受益。

3. chezmoi 配置

3.1 安装

brew install chezmoi

3.2 准备 GitHub 仓库

在 GitHub 上创建一个私有 dotfiles 仓库(名称自定)。空仓库即可。

3.3 初始化 chezmoi

chezmoi init github.com/yourname/dotfiles
# 或,如果可以使用 SSH:
chezmoi init git@github.com:yourname/dotfiles.git

~/.local/share/chezmoi/ 成为工作树(实际的 Git 仓库)。

3.4 添加文件

# 将 .zshrc 纳入 chezmoi 管理
chezmoi add ~/.zshrc
 
# 或一次添加多个
chezmoi add ~/.gitconfig ~/.tmux.conf ~/.config/starship.toml

文件以 ~/.local/share/chezmoi/dot_zshrc 形式复制(前导点 → dot_ 前缀)。

3.5 提交 + 推送

chezmoi cd          # 跳转到工作树
git add .
git commit -m "init dotfiles"
git push -u origin main
exit                # 返回之前的位置

3.6 在新机器上恢复

# 在新 Mac 上
brew install chezmoi
chezmoi init --apply github.com/yourname/dotfiles

完成。所有 dotfiles 立即在 ~ 中生成并应用。

4. 按机器分支(模板)

chezmoi 最强大的功能。同一个 .gitconfig 根据工作/个人场景自适应:

~/.local/share/chezmoi/dot_gitconfig.tmpl

内容:

[user]
    name = Your Name
{{- if eq .chezmoi.hostname "Work-MacBook" }}
    email = me@company.com
    signingkey = AAAA....
{{- else }}
    email = personal@example.com
{{- end }}
 
[core]
    editor = nvim
    autocrlf = input

.tmpl 扩展名标记为模板。chezmoi 在应用时根据主机名进行分支。

4.1 可用变量

chezmoi data       # 打印所有上下文变量

常用变量:

  • .chezmoi.osdarwin / linux / windows
  • .chezmoi.hostname — 机器名
  • .chezmoi.archarm64 / amd64
  • 自定义 — 通过 chezmoi edit-config 添加

4.2 OS 专属文件

dot_zshrc 重命名为 dot_zshrc.tmpl,按 OS 分支:

{{ if eq .chezmoi.os "darwin" -}}
# 仅 macOS
export HOMEBREW_PREFIX="/opt/homebrew"
eval "$($HOMEBREW_PREFIX/bin/brew shellenv)"
{{ else if eq .chezmoi.os "linux" -}}
# 仅 Linux
export PATH="$HOME/.linuxbrew/bin:$PATH"
{{ end -}}
 
# 通用
alias ll='ls -lah'

5. 密钥集成

永远不要将 API 密钥或 Token 直接写入 dotfiles。使用 chezmoi 的密钥工具集成:

1Password CLI

brew install --cask 1password 1password-cli
op signin

dot_ssh/config.tmpl

Host github.com-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
  PreferredAuthentications publickey

引用密钥的 dot_env.tmpl

export ANTHROPIC_API_KEY={{ onepasswordRead "op://Private/Anthropic/api_key" }}
export GITHUB_TOKEN={{ onepasswordRead "op://Private/GitHub/token" }}

执行 chezmoi apply 时,它会从 1Password 获取值并写入明文 .env该明文文件在 .gitignore 中,永远不会进入仓库。

Bitwarden / pass / age

每种都有官方 chezmoi 集成 — 参见 docs.chezmoi.io

6. 工作流

日常

# 直接编辑 ~/.zshrc 后
chezmoi diff       # 查看变更
chezmoi add ~/.zshrc   # 将变更同步回仓库
chezmoi cd && git commit -am "tweak zshrc" && git push

同步另一台机器

chezmoi update     # git pull + apply

预览变更

chezmoi diff       # 应用前查看变更
chezmoi apply -v   # 详细应用

编辑源文件

chezmoi edit ~/.zshrc   # 编辑源文件(= 仓库)并自动应用

7. yadm — 最轻量的替代方案

如果零学习成本是首要目标,选择 yadm:

brew install yadm
yadm init
yadm add ~/.zshrc
yadm commit -m "init"
yadm remote add origin git@github.com:yourname/dotfiles.git
yadm push -u origin main
 
# 在另一台机器上
yadm clone git@github.com:yourname/dotfiles.git

命令与 git 完全相同(只是二进制名称不同)。缺点:按机器分支仅限 .zshrc##os.Darwin 等 alt 文件。

8. 原始符号链接 + Git

最小依赖:

mkdir ~/dotfiles && cd ~/dotfiles
git init
mv ~/.zshrc ~/dotfiles/zshrc
ln -s ~/dotfiles/zshrc ~/.zshrc
 
# install.sh
#!/usr/bin/env bash
for f in zshrc gitconfig tmux.conf; do
  ln -sf "$HOME/dotfiles/$f" "$HOME/.$f"
done

简洁清晰,但密钥管理、按机器分支和引导均需自行实现。大多数人在一年内会迁移到 chezmoi。

如何验证

  1. chezmoi diff → 无变更(所有内容已应用)
  2. 直接编辑 ~/.zshrcchezmoi diff 显示差异
  3. 在新机器(或干净的虚拟机)上运行 chezmoi init --apply github.com/you/dotfiles → 所有 dotfiles 恢复
  4. 修改模板后,chezmoi apply -v → 根据主机名输出不同内容
  5. 集成 1Password 后,chezmoi apply 将明文写入 ~/.env,但仓库中不包含该文件

故障排除

chezmoi apply 没有变化

  • 检查 chezmoi diff。如果为空,属于正常情况。
  • 文件权限差异可能隐藏变更 — 尝试 chezmoi apply --force

模板语法错误

{{ ... }} 是 Go 模板。缺少结束 -}} 和变量拼写错误很常见。用 chezmoi execute-template < dot_gitconfig.tmpl 进行演习。

1Password 集成失败

  • op signin 后,会话默认有效约 30 分钟。再次运行 eval $(op signin)
  • chezmoi.toml 中显式启用 1Password(chezmoi edit-config)。

新机器上 SSH 密钥缺失

永远不要将 SSH 密钥本身存入 dotfiles(安全考虑)。在新机器上生成新密钥并注册到 GitHub。chezmoi 只应管理 ~/.ssh/config 等配置文件。

~/.zshrc 直接编辑后不更新

使用 chezmoi edit ~/.zshrc(编辑源文件,自动应用)。或直接编辑源文件后执行 chezmoi apply

参考资料

更新日志

  • 2026-05-12:首次发布。三种方案对比 + chezmoi 实战配置(模板 / 密钥 / 工作流)+ 五个故障排除案例。