chezmoi による dotfiles 管理
~/.zshrc や ~/.gitconfig などの dotfiles(ドットファイル)を git で管理し、複数マシンに展開するための要素技術です。ここでは代表的なツールである chezmoi を中心に解説します。
dotfiles とは
ホームディレクトリ直下にある、ドットで始まる設定ファイル群のことです。
- シェル:
.zshrc/.bashrc/.profile - Git:
.gitconfig/.gitignore_global - エディタ:
.vimrc/.config/nvim/など
これらは環境構築の「要」ですが、ホーム直下に散らばっているため、そのままでは git 管理しにくいという課題があります。
なぜ単純な git 管理では駄目なのか
ホームディレクトリ全体を git リポジトリにすると、意図しないファイルまで管理対象になりがちです。この問題への代表的な解決策を比較します。
| 方式 | 仕組み | 特徴 |
|---|---|---|
| シンボリックリンク (GNU stow) | dotfiles を別ディレクトリに置き、ホームへ symlink を張る | シンプルだが symlink 管理が煩雑になりがち |
| bare git リポジトリ | ホーム直下で .git だけを持ち、worktree をホームにする | 追加ツール不要だが、誤操作のリスクが高い |
| chezmoi | ソースとターゲットを分離し、テンプレート・差分適用を提供 | 冪等・テンプレート・差分確認が揃う |
| dotbot / home-manager など | 宣言的な dotfiles 管理 | エコシステムごとの学習コスト |
chezmoi は Go 製の単一バイナリで、以下の特長があります。
- ソースディレクトリ(管理対象の実体)とホーム(ターゲット)を分離
diff/applyによる冪等な適用- テンプレート(
{{ }})によるマシン別の出し分け - パスワード管理ツールとの連携
基本概念: ソースとターゲット
chezmoi は ソース状態(source state) と ターゲット状態(target state) の 2 つを管理します。
- ソース状態: リポジトリ内の
dotfiles/ディレクトリ(管理対象の実体) - ターゲット状態: 実際のホームディレクトリ(
~/.zshrcなど)
ファイル名の先頭に dot_ を付けるのが規約です。dot_zshrc は ~/.zshrc に対応します。
dotfiles/
├── dot_zshrc → ~/.zshrc
├── dot_bashrc → ~/.bashrc
├── dot_profile → ~/.profile
└── dot_gitconfig → ~/.gitconfig
apply はソースからターゲットへ、add はターゲット(ホームの実ファイル)からソースへ取り込む方向です。
よく使うワークフロー
chezmoi を薄くラップしたスクリプト(chezmoi.sh)を介して操作すると、ソースディレクトリを毎回指定する手間を省けます。
chezmoi diff # 適用される差分を確認 (まずこれ)
chezmoi apply # ソースをホームへ適用
chezmoi add ~/.zshrc # ホームの変更をソースへ取り込む
chezmoi edit dot_zshrc # ソースを編集
# ラッパースクリプトの例 (chezmoi.sh)
exec chezmoi --source "$(dirname "$0")/dotfiles" "$@"
運用上の原則は「ホーム側を直接編集しない」ことです。
- 設定を変えたい → リポジトリの
dotfiles/を編集してapply - ホーム側を先に編集してしまった →
addで取り込む(差分を必ず確認)
これにより「ホームにしかない変更」がリポジトリに取り込まれず、環境の再現性が保たれます。
マシン固有・機密の設定の分離
すべての設定を git 管理すると、機密情報やマシン固有の値までリポジトリに入ってしまいます。定石は「本体の dotfile の末尾で .local ファイルを読み込む」方法です。
# .zshrc の末尾
[ -f "$HOME/.zshrc.local" ] && source "$HOME/.zshrc.local"
リポジトリには雛形(zshrc.local.example)だけを置き、実体は各マシンで作成します。トークンなどの機密はこの .local ファイルに書きます(必要なら chmod 600)。
Git の認証情報を dotfiles に入れない
.gitconfig を管理する際の注意点は、認証情報を dotfiles に含めないことです。GitHub CLI(gh)が保持する認証情報を credential helper として流用すると、dotfiles には設定だけを置き、実トークンはツール側に任せられます。
# ~/.gitconfig の例
[init]
defaultBranch = main
[credential "https://github.com"]
helper =
helper = !gh auth git-credential
この gh auth git-credential は、gh が管理する認証情報を Git の credential helper として使うものです。機密そのもの(トークン)は ~/.config/gh/ に置かれ、dotfiles には入りません。