GNU Stow の限界—シンボリックリンク管理の落とし穴

元記事の著者は、複数の Mac(MacBook Pro、MacBook Air、Mac Mini)で dotfiles を管理する際に、GNU Stow を数年間運用してきました。Stow はシンボリックリンクを使ってホームディレクトリの設定ファイルを Git リポジトリと連動させるシンプルな仕組みが特徴です。

しかし複数マシン管理になると、この仕組みが問題になります。各マシンで Stow リポジトリのクローンを持つと、ファイルの編集が自動的にリポジトリに反映される「シンボリックリンク経由の直接書き込み」により、マシン間で意図しない差分が発生するのです。

複数マシンでシンボリックリンク経由の管理をすると、ある機械での編集が別の機械の変更と競合し、リポジトリの状態を保つのが徐々に負担になる。

さらに新しいマシンをセットアップする際も手間が増えます。Homebrew などで既に作成されているファイル(~/.zprofile、~/.gitconfig など)は Stow でリンクできず、手動削除と再設定が必要になるため、ブートストラップ処理が煩雑になるという実体験が語られています。

Chezmoi の設計—ソースを単一の真実に

これに対して Chezmoi は異なるアプローチを採っています。~/.local/share/chezmoi というディレクトリをソースの真実として機能させ、実際のホームディレクトリには 実ファイル(シンボリックリンクではない) を配置する仕組みです。

ファイル名の接頭辞にメタデータを埋め込む工夫が特徴的です。

メタデータ 用途 例
dot_ ドット付きファイル名を表現 ~/.zshrc → dot_zshrc
private_ グループ・その他のパーミッションを剥奪 private_dot_ssh_config
.tmpl Go テンプレート対応(マシン固有設定可能) .chezmoi.toml.tmpl

chezmoi add ~/.zshrc でファイルをリポジトリに登録すると、ファイル名が自動的に変換されて管理されます。重要なのは、以降の編集は ソースディレクトリを経由してのみ 反映されるという点です。

ソースディレクトリを単一の真実として機能させることで、マシン間での意図しない差分競合を根本的に排除できる。

マシン固有設定への対応—テンプレート活用

複数マシン運用では、OS やツールバージョンに応じた条件付き設定が必要になります。Chezmoi はこれを Go テンプレート機能で解決しています。

たとえば macOS 特有の設定スクリプトは .chezmoiscripts/macos/ に配置されており、以下のようなファイルが含まれています:

  • run_onchange_before_install-homebrew-bundle.sh.tmpl
  • run_onchange_after_init-macos-machine.sh.tmpl
  • run_onchange_after_disable-macos-animations.sh

このほか、Brewfile(Homebrew パッケージ定義)も同じリポジトリで管理されているため、shell 設定ファイルとパッケージ管理が統一されたワークフローになります。

著者は .chezmoi.toml.tmpl でマシンごとの変数を定義し、テンプレート内でそれらを参照する構成を採用しており、シンプルながら柔軟な仕組みが実現されています。

実運用で見えてくる利点と学習コスト

実運用を重ねると、Chezmoi のアプローチが開発ワークフローに自然に馴染むことがわかります。特に以下の点が実用的です:

  • 差分管理が明示的:chezmoi diff でソースとホーム側のズレを視覚的に確認できる
  • 新マシンセットアップの簡素化:リポジトリをクローンして chezmoi apply するだけで、設定ファイルもスクリプト実行も一度に済む
  • エージェント skill ファイルも管理可能:著者は Claude や同類の AI ツール向けスキル定義も同じリポジトリで追跡している

ただし、Stow の「ほぼ学習曲線がない」というシンプルさに比べると、テンプレート機能や実行スクリプトの仕組みを理解するには若干の学習が必要です。それでも、複数マシン管理の手間を考えると十分な価値があると著者は評価しています。

実装の実例—dot_agents と Claude integration

記事に示されているソースツリーを見ると、著者の実装の工夫が垣間見えます。特に dot_agents/skills/ ディレクトリに、複数のエージェント skill を管理している点は、AI ツール周りを扱うエンジニアにとって参考になるでしょう。

このような構成により、dotfiles リポジトリが単なる shell 設定や git 設定の保管庫ではなく、開発全体の「マシン固有メタデータ」を統一的に管理するハブになる可能性が示唆されています。