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

pushfetch 用于与远程仓库同步;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 用于匹配规则文件的符号链接;encryptdecrypt 用于加密/解密配置文件;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 statusyadm diffyadm 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-releaseID_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 j2clienvtpl 功能强大的 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 的组合让它在处理复杂多机环境时非常强大。

参考资料