tldr:常用命令速记
yadm 基于 Git,使用时会把 $HOME 当作工作目录,因此你可以在任意目录下管理 dotfiles。
查看与对比
man yadm
yadm status
yadm diff
yadm diff --cached
yadm list -a
status 查看仓库状态;diff 查看未提交改动;diff --cached 查看已暂存改动;list -a 查看所有受管理文件。
同步与提交
yadm push
yadm fetch
yadm commit --amend
push 和 fetch 用于与远程仓库同步;commit --amend 用于修正上一次提交。
文件与分支
yadm checkout -- <file>
yadm checkout -b <branch-name>
checkout -- <file> 放弃本地更改并恢复为 HEAD 版本;checkout -b 创建并切换到新分支。
进阶功能
yadm alt
yadm encrypt
yadm decrypt
yadm decrypt -l
yadm clone --bootstrap <URL>
yadm remote -v
alt 用于匹配规则文件的符号链接;encrypt 和 decrypt 用于加密/解密配置文件;clone --bootstrap 用于克隆后自动初始化;remote -v 用于查看远程仓库信息。
详细介绍
yadm(Yet Another Dotfiles Manager)是一个基于 Git 的 dotfiles 管理工具,直接以 $HOME 为工作目录,让你像管理代码一样管理配置文件。
一、yadm 是什么
| 特性 | 说明 |
|---|---|
| 基于 Git | 所有操作底层都是 Git,学习成本极低 |
工作目录 = $HOME |
直接管理 ~/.bashrc、~/.vimrc 等,无需创建额外目录 |
| 裸仓库 | Git 仓库存在 ~/.local/share/yadm/repo.git,不污染家目录 |
| Alternates | 根据 OS/主机名/用户自动切换不同版本的配置文件 |
| Templates | 用 Jinja/ESH 语法在配置文件中嵌入动态内容 |
| Encryption | 内置 GPG/OpenSSL 加密,安全同步 SSH 密钥等敏感文件 |
[!notice]
由于 一些 api 密钥可能会保存在 zshrc 等文件中,这里推荐将 github 仓库设置成私密仓库,如果是公网服务器或者其他可信设备克隆配置的话,可以使用 ssh 协议克隆,这样可以避免网络连接和泄密的问题
当然也可以使用 yadm 的加密功能,不过我暂时还不够熟悉,所以先搭建一个可以用的工作流,后续熟练了再补充
二、安装
# macOS
brew install yadm
# Ubuntu/Debian
sudo apt install yadm
# Arch
sudo pacman -S yadm
# 任意 Linux(无需 root,直接下载二进制)
curl -fLo /usr/local/bin/yadm https://github.com/TheLocehiliosan/yadm/raw/master/yadm
chmod a+x /usr/local/bin/yadm
三、从零开始:初始化仓库
3.1 新建仓库
# 初始化 yadm 仓库(仓库在 ~/.local/share/yadm/repo.git)
yadm init
# 添加你的配置文件
yadm add ~/.bashrc
yadm add ~/.vimrc
yadm add ~/.config/git/config
# 提交
yadm commit -m "Initial dotfiles"
# 添加远程并推送
yadm remote add origin https://github.com/yourname/dotfiles.git
yadm push -u origin master
💡 所有不认识的
yadm xxx命令都会透传给 Git,所以yadm status、yadm diff、yadm log等全部和 Git 用法一样。
我的 github仓库 https://github.com/tkzzzzzz6/My_Dotfiles.git
3.2 在新机器上克隆
# 克隆已有的 dotfiles 仓库
yadm clone https://github.com/yourname/dotfiles.git
# 如果有冲突文件(本地已有同名配置),yadm 不会覆盖,需要手动解决
# 查看冲突:
yadm status
# 强制使用仓库版本覆盖本地:
yadm checkout --overwrite -- ~/.bashrc
四、日常使用(和 Git 完全一样)
yadm status # 查看哪些配置文件被修改
yadm diff ~/.bashrc # 查看某个文件的改动
yadm add ~/.config/nvim/init.vim
yadm commit -m "Update nvim config"
yadm push
yadm pull # 同步远程更新
yadm log --oneline # 查看提交历史
yadm list # 列出所有被管理的文件
yadm list -a # 列出所有文件(包括 alternates 和 templates)
git add -u 来添加所有已经被追踪到文件
五、核心特性 1:Alternates(多系统适配)
这是 yadm 最强大的功能。同一台机器上的 ~/.bashrc 可以自动指向不同的实际文件,根据 OS / 主机名 / 用户 / class 等条件智能选择。
5.1 命名规则
创建带后缀的文件,yadm 会自动创建符号链接:
文件名##<条件>[,<条件>,...]
5.2 支持的匹配条件
| 条件 | 缩写 | 自动检测方式 | 示例值 |
|---|---|---|---|
template |
t |
模板处理器 | default, j2, esh |
user |
u |
id -u -n |
alice, bob |
hostname |
h |
uname -n |
macbook, server01 |
class |
c |
手动设置 | work, personal |
distro |
d |
lsb_release -si |
Ubuntu, Arch |
distro_family |
f |
/etc/os-release 的 ID_LIKE |
debian, arch |
os |
o |
uname -s |
Linux, Darwin, WSL |
arch |
a |
uname -m |
x86_64, arm64 |
default |
- | 无其他匹配时 | default |
extension |
e |
仅影响语法高亮 | .sh, .conf |
5.3 实际例子
假设你的仓库中有这些文件:
~/.bashrc##default
~/.bashrc##os.Darwin
~/.bashrc##os.Linux
~/.bashrc##os.Linux,hostname.ubuntu-server
~/.bashrc##class.Work
在不同机器上,yadm 会自动创建对应的符号链接:
# macOS 笔记本(hostname: macbook-pro)
~/.bashrc -> ~/.bashrc##os.Darwin
# 普通的 Linux 机器
~/.bashrc -> ~/.bashrc##os.Linux
# Linux 且 hostname 为 ubuntu-server
~/.bashrc -> ~/.bashrc##os.Linux,hostname.ubuntu-server
# 设置了 class 为 Work(见下文)
~/.bashrc -> ~/.bashrc##class.Work
5.4 设置 class(手动标记机器类型)
yadm config local.class Work # 标记为工作机
yadm config local.class Personal # 标记为个人机
yadm config --add local.class Gaming # 可设置多个 class
匹配优先级:条件越多越优先。
os.Linux,hostname.server会胜过os.Linux。
5.5 关闭自动链接(如需手动控制)
yadm config yadm.auto-alt false
# 需要时手动运行:
yadm alt
六、核心特性 2:Templates(模板)
用一个模板文件动态生成配置内容,适合需要在不同机器上嵌入不同值的场景。
6.1 支持的模板引擎
| 引擎 | 后缀 | 依赖 | 说明 |
|---|---|---|---|
| default | ##template 或 ##template.default |
awk |
yadm 内置,轻量,Jinja-like 语法 |
| Jinja | ##template.j2 |
j2cli 或 envtpl |
功能强大的 Python 模板 |
| ESH | ##template.esh |
esh |
可在模板中执行 Shell 命令 |
6.2 内置模板示例
创建 ~/.gitconfig##template:
{% if yadm.os == "Darwin" %}
[name]
email = alice@company.com
{% else %}
[name]
email = alice@personal.com
{% endif %}
[core]
editor = vim
yadm 会自动处理成 ~/.gitconfig:
- macOS 上:
email = alice@company.com - 其他系统:
email = alice@personal.com
6.3 模板中可用的变量
yadm.user # 当前用户名
yadm.hostname # 主机名(短)
yadm.os # Linux / Darwin / WSL
yadm.arch # x86_64 / arm64
yadm.distro # Ubuntu / Arch / Fedora
yadm.distro_family # debian / arch / rhel
yadm.class # 设置的 class
yadm.classes # 所有 class(空格分隔)
七、核心特性 3:Encryption(加密)
安全同步 SSH 私钥、GPG 密钥等敏感文件。
7.1 配置要加密的文件列表
# 编辑加密列表
cat > ~/.config/yadm/encrypt << 'EOF'
.ssh/id_rsa
.ssh/id_ed25519
.gnupg/secring.gpg
.aws/credentials
EOF
# 加密(会提示输入密码,生成 archive 文件)
yadm encrypt
# 将加密后的 archive 提交到仓库
yadm add ~/.local/share/yadm/archive
yadm add ~/.config/yadm/encrypt
yadm commit -m "Add encrypted secrets"
yadm push
7.2 解密
# 在新机器上克隆后解密:
yadm decrypt
# 输入密码即可
7.3 使用 GPG 非对称加密(更安全)
# 指定你的 GPG 公钥 ID
yadm config yadm.gpg-recipient YOUR_KEY_ID
# 或用 ASK 交互式选择
yadm config yadm.gpg-recipient ASK
# 这样 encrypt 时用公钥加密,decrypt 时用私钥自动解密,无需输密码
yadm encrypt
7.4 切换加密引擎
yadm config yadm.cipher openssl # 默认是 gpg
八、Bootstrap(自动初始化脚本)
在新机器上克隆 dotfiles 后自动安装软件、执行初始化。
8.1 创建 bootstrap 脚本
cat > ~/.config/yadm/bootstrap << 'EOF'
#!/bin/bash
echo "=== Bootstrapping dotfiles ==="
# 安装 Homebrew(macOS)
if [[ "$(uname -s)" == "Darwin" ]]; then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew bundle --file=~/.config/Brewfile
fi
# 安装 vim-plug
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
# 安装 vim 插件
vim +PlugInstall +qall
# 设置 shell
chsh -s $(which zsh)
echo "=== Done ==="
EOF
chmod +x ~/.config/yadm/bootstrap
yadm add ~/.config/yadm/bootstrap
yadm commit -m "Add bootstrap script"
8.2 克隆时自动执行
yadm clone https://github.com/yourname/dotfiles.git --bootstrap
或克隆后手动执行:
yadm bootstrap
九、常用配置
# 查看所有配置
yadm config --list
# 关闭自动权限修复
yadm config yadm.auto-perms false
# 使用硬拷贝代替符号链接(某些系统不支持 symlink)
yadm config yadm.alt-copy true
# 加密后自动从 Git 追踪中排除(默认开启,防止误提交明文)
yadm config yadm.auto-exclude true
# 显示未追踪文件(默认隐藏,避免 $HOME 下文件太多干扰)
yadm gitconfig --unset status.showUntrackedFiles
十、完整工作流示例
# ========== 第一台机器 ==========
yadm init
yadm add ~/.bashrc ~/.vimrc ~/.config/git/config
yadm commit -m "Initial dotfiles"
yadm remote add origin https://github.com/yourname/dotfiles.git
yadm push -u origin master
# 添加 Mac 专用配置
cp ~/.bashrc ~/.bashrc##os.Darwin
yadm add ~/.bashrc##os.Darwin
yadm commit -m "Add macOS-specific bashrc"
# 添加加密文件
echo ".ssh/id_rsa" >> ~/.config/yadm/encrypt
yadm encrypt
yadm add ~/.config/yadm/encrypt ~/.local/share/yadm/archive
yadm commit -m "Add encrypted SSH key"
# ========== 第二台机器(Linux) ==========
yadm clone https://github.com/yourname/dotfiles.git
yadm decrypt # 解密 SSH 密钥
yadm bootstrap # 运行初始化脚本
yadm alt # 自动创建正确的符号链接
# ~/.bashrc 自动指向 ~/.bashrc##os.Linux
总结
| 需求 | yadm 方案 |
|---|---|
| 管理 dotfiles | yadm init + yadm add/commit/push |
| 多系统不同配置 | Alternates (##os.Linux, ##os.Darwin) |
| 配置里嵌入动态值 | Templates (##template) |
| 安全同步 SSH/GPG 密钥 | yadm encrypt / yadm decrypt |
| 新机器一键初始化 | yadm clone <url> --bootstrap |
| 迁移到 yadm(已有 Git 仓库) | yadm clone 或直接 yadm init + 手动添加文件 |
yadm 的哲学是**”不要改变你的工作流,只改变你管理配置的方式”**。会用 Git 就会用 yadm,上手极快,但 Alternates + Templates + Encryption 的组合让它在处理复杂多机环境时非常强大。