从GNU Stow迁移到Chezmoi
我已经用GNU Stow管理我的点文件(dotfiles)好几年了。实际上,我甚至在2023年还写过一篇关于这种设置的文章,标题有些土。Stow对我来说一直很有效,但在多个设备之间管理符号链接慢慢变得令人痛苦。所以我开始寻找更好的工具,甚至考虑自己编写一个。然后一个同事向我推荐了chezmoi,到目前为止我对它非常满意。它满足了我所有的需求,我也开始用它来追踪我的代理技能文件。我所使用的机器有三台Mac:一台MacBook Pro(用于工作),一台MacBook Air(用于个人),还有一台Mac Mini(作为小型私人服务器)。我主要从其他两台机器SSH进入Mac Mini。它毕竟还是一台Mac,而且我在上面使用的是自己的shell,所以相同的点文件适用。我还保留了一些Linux虚拟机,但我很少在服务器上需要我的点文件。Ansible负责配置这些。这个工作流专门针对桌面机器。当我克服Stow的局限性时,Stow的模型是符号链接。配置文件存储在一个git仓库中,按照Stow所说的包(packages)分组,stowing一个包会将其文件链接到主目录。对于单个机器来说,它仍然可以使用。命令是幂等的,几乎不需要学习。问题在于,符号链接是双向的。每次在每台机器上的编辑都会直接写入该机器的该仓库克隆中。几个月后,我会发现Air上有些肮脏的工作树,其更改我完全不记得。它们的一半与Pro上已经推送的内容相冲突。保持三份克隆一致变得异常繁琐。新机器则是另一个问题。Stow不能链接到一个真实文件。到新Mac上运行Homebrew和几个工具时,像~/.zprofile和~/.gitconfig的文件已经存在。引导工作意味着克隆仓库,手动删除冲突文件,并在尝试记住我命名的包的同时重新stow每一个包。而Stow只能处理文件。Homebrew包和macOS设置存储在我必须记得按正确顺序执行的单独脚本中。如何使用chezmoi Chezmoi在~/.local/share/chezmoi下保持一个源目录,这也是一个常规的git仓库。chezmoi add ~/.zshrc会将实时文件复制到该目录并命名为dot_zshrc。添加~/.config/gh/config.yml会创建dot_config/gh/config.yml(包括父目录)。我从来不手动创建这些名称,因为chezmoi add会根据真实路径推导出它们。目录结构最终映射到主目录,每个以点(.)开头的文件都以dot_前缀拼写。dot_是chezmoi编码到文件名中的几个属性之一。private_前缀会从文件中删除组和全局权限。后缀.tmpl会将文件转换为可以读取每台机器数据的Go模板。我使用模板很少,而且所有的模板都会在这篇文章的后面出现。chezmoi apply 则是反向操作。它将每个被跟踪的文件写回到其名拼写出的主目录路径,这样dot_zshrc就会放到~/.zshrc。复制的是实际文件,而不是符号链接。源目录是唯一的真实来源。当主目录中的文件不再与其源副本匹配时,chezmoi diff会显示差异,而下一个apply会将其恢复。失去符号链接的自动写入特性证明是我最喜欢的功能。除非我故意在那里进行更改,否则仓库中的内容不会改变。我跟踪的所有内容都位于该源目录中。chezmoi cd会让我进入一个子shell,这里是整个结构:~/.local/share/chezmoi ├── .chezmoi.toml.tmpl ├── .chezmoiignore ├── .chezmoiscripts │ └── macos │ ├── run_onchange_after_disable-macos-animations.sh │ ├── run_onchange_after_init-macos-machine.sh.tmpl │ └── run_onchange_before_install-homebrew-bundle.sh.tmpl ├── .gitignore ├── Brewfile ├── README.md ├── dot_agents │ └── skills │ ├── go-modernize │ ├── go-styleguide │ └── meatspeak ├── dot_claude │ ├── settings.json │ └── symlink_skills.tmpl ├── dot_codex │ └── private_config.toml ├── dot_config │ ├── gh │ │ ├── config.yml │ │ └── private_hosts.yml │ └── ghostty │ └── config ├── dot_gitconfig ├── dot_gitconfig-pers ├── dot_gitconfig-werk ├── dot_shellcheckrc ├── dot_zsh_aliases └── dot_zshrc 这个列表很短,因为我不喜欢自定义工具,尽量保持默认设置。点文件本身包括zsh、git、shellcheck、ghostty和GitHub CLI的配置。我也跟踪Claude Code的settings.json和Codex的config.toml,以便所有代理在每台机器上表现一致。gh的hosts.yml和Codex配置上的private_前缀使这两个文件的权限为0600。关于dot_agents下的技能我会在最后讨论。三份gitconfig分开了我的身份。我的所有项目都存放在两个目录下,~/canvas/werk/用于工作,~/canvas/pers/用于个人,两个目录在每台机器上都有。主要的gitconfig通过仓库所在的位置来路由身份: [includeIf "gitdir:~/canvas/pers/"] path = ~/.gitconfig-pers [includeIf "gitdir:~/canvas/werk/"] path = ~/.gitconfig-werk 存放在~/canvas/pers/下的仓库会使用我的个人配置...
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡