chezmoi でローカル側とソースディレクトリ側の差分を解消するときに、1 ファイルずつ差分を表示した上で「ローカル側を登録するか / ソース側を適用するか / 保留するか」を訊いて対応してくれるラッパーシェルスクリプトを書きました。
恒常的に PC 2 台以上で作業するケースで役立つと思います (PC 移行時に個人設定を運搬するのみの場合や、メイン PC 以外で個人設定を変更しない場合は役立たないと思います)。
chezmoi v2.69.3 での動作を確認しています。特に次に依存します。
-
chezmoi diffの結果がdiff --git a/.bashrc b/.bashrcといった行を含む (3 番目の要素の先頭a/を削るとホームからのパスになる) ことを期待します。 -
chezmoi managed --include=templates ~/.bashrcの結果、そのファイルがテンプレート化されて登録されていたらそのファイルを表示、そうでなければ何も表示しないことを期待します (--include=encryptedも同様)。
シェルスクリプト本体
以下の helper.sh をソースディレクトリ ~/.local/share/chezmoi/ に配置し、ソースディレクトリでこれを実行する想定です (このスクリプト自体はローカルに反映されるべきではないので .chezmoiignore に記述します)。
~/.local/share/chezmoi/helper.sh
#!/usr/bin/bash
while IFS= read -r line; do
filename="${line:2}"
echo "----- ローカルとソースディレクトリに差分があります -----"
echo "${HOME}/${filename}"
chezmoi diff "${HOME}/${filename}"
tmpl=0
encrypt=0
count=$(chezmoi managed --include=templates "${HOME}/${filename}" | wc -l)
[ "$count" -gt 0 ] && { tmpl=1; echo "※ テンプレート化されて登録されています"; }
count=$(chezmoi managed --include=encrypted "${HOME}/${filename}" | wc -l)
[ "$count" -gt 0 ] && { encrypt=1; echo "※ 暗号化されて登録されています"; }
echo "${HOME}/${filename} への操作を選択してください"
read -p "l=ローカルを登録, s=ソースを適用, n=何もしない, q=終了 > " key < /dev/tty
if [ "$tmpl" -eq 1 ] && [ "$key" == "l" ]; then
echo "[ERROR] テンプレートファイルはローカルから登録できません"
exit 0
fi
if [ "$key" == "s" ]; then
echo "本当にソースを適用してローカルを上書きしてよいですか?"
echo "(サブ機への同期、テンプレートでソース編集したときのみ想定される操作)"
read -p "l=ローカルを登録, s=ソースを適用, n=何もしない, q=終了 > " key < /dev/tty
fi
case "$key" in
q) exit 0 ;;
n) : ;;
l)
echo "ローカルを登録します"
[ "$encrypt" -eq 0 ] && chezmoi add "${HOME}/${filename}"
[ "$encrypt" -eq 1 ] && chezmoi add --encrypt "${HOME}/${filename}"
;;
s)
echo "ソースを適用します"
chezmoi apply "${HOME}/${filename}"
;;
esac
done < <(chezmoi diff | grep "^diff " | awk "{print \$3}")
echo
git status -s
基本的な流れ
このシェルスクリプトの基本的な流れは以下です。
- ローカルとソースディレクトリで差分がある各ファイルについて、
- 差分を提示します。
- どうするか訊きます。
l=ローカルを登録, s=ソースを適用, n=何もしない, q=終了
-
lかsが選択されたら登録か適用を実行します。nが選択されたら何もせず次のファイルにいきます。qが選択されたらこのスクリプト実行自体を終了します。
- 最後にソースディレクトリでの
git status -sの結果を表示します (Git へのコミットが必要なファイルを確認する用)。
注意点
-
sが選択されたときは再確認します。- もし意図せずソースを適用すると、ローカル変更が失われるためです。
- ただし、実際ローカルが新しい場合は chezmoi も再確認するため 2 重確認になり、またこの場合は chezmoi の上書き後に再度エンターを打たないと進まないことがあります。煩わしいならこの再確認の
ifブロックは撤去してよいかもしれないです。
-
lが選択され、もしそのファイルが暗号化されて登録されている場合は、再登録も暗号化して実施します (chezmoi add --encrypt)。 -
lが選択され、もしそのファイルがテンプレート化されて登録されている場合は、登録を拒否してスクリプト実行自体を終了します。-
chezmoi add --templateでローカルを登録してしまうと再度くり抜きが必要になるため、テンプレート化ファイルはソースディレクトリ側の編集を想定しています。
-