設定ファイルをVCSで管理するという発想は昔からあります。古くはRCSを使ったり、今時は/etcのようなシステムワイドな設定であれば、etckeeperが使えますが、ホームディレクトリの設定ファイルとなると若干面倒です。
Qiita上でも"git 設定ファイル"や"git dotfile"で検索すれば複数ヒットしますが、ほとんどが「$HOME直下ではないどこかのサブディレクトリにリポジトリをおいてシンボリックリンクを貼る」という手法が支配的のようです。
その方法はお手軽であるものの、使っているツール自身がdotfileを書き換えることがある場合に不都合が起きることがあります。元ファイルをバックアップにrenameして新たに同じファイル名で新規作成する挙動をするアプリケーションがあるからです。このような場合、symlinkが切れてしまいます。
他の方法を探してみたところ、The best way to store your dotfiles: A bare Git repository - Atlassian Developersというブログの記事の手法が良さそうでした。以下はブログからのsnippetの引用です。
git init --bare $HOME/.cfg
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
config config --local status.showUntrackedFiles no
echo "alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.bashrc
この設定のポイントは以下にあります。
- gitディレクトリ名を".git"とは違う名前にする
- aliasで変えたgitディレクトリ名とワーキングディレクトリを明示する
これらの措置によって、通常のgitコマンドを使う分には$HOME自体がgitの管理対象と判断されなくなり、普段のgit操作に支障をきたすことなく直接$HOME直下のdotfileを管理できます。
自分はzshを使っているので、以下のような設定を追加しました。
setopt complete_aliases
zshで補完を有効にしていると、alias内のコマンドが補完対象だった場合に同じように補完を試みてきます。しかしサブコマンド以外のファイル名補完ができません($HOME/.gitが存在しないためワーキングディレクトリとして認識されない)。
このalias単体だけどうにかする方法も考えましたが(専用の補完関数を作る、aliasでなく関数で定義してみる等)どうもうまく行かなかったので、zsh側の挙動を変更することにしました。他に良いアイディアがあればコメントください。