Git管理下でローカル編集した差分を検知除外したい時にはgitignoreではなくgit update-indexを使おう

環境に合わせた修正を差分として検知させたくなく、gitignoreに追加していました。が、結果は変わらず。動作を確認してみると、git update-indexを使うことが動作としては期待するものになると理解しました。環境依存の設定であるため、個々で指定が必要になります。
2021.01.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

gitでのバージョン管理対象にしつつも、編集差異を検知させたくないというケースは時折あります。環境変数設定用ファイルの内容をプロジェクト共通の初期値にしておき、各々の環境に合わせて調整する等。

.gitignoreに突っ込んで完了」と思いきや、バッチリと差分が検知されました。上手くマッチしていないのかと表記をあれこれ試していましたが、そもそものやり方が違っていることを知りました。

知っている方は多いかもしれませんが、知らない場合に慌てることを防ぐ意味でやり方を書いてみました。

git update-index

適用すると結果として差分が表示されなくなりますが、オプションによって扱いが異なるため目的に応じた使い分けが必要です。

--skip-worktree

git update-index --skip-worktree

手元の環境で発生した変更をGitに検知してほしくない場合に用います。冒頭のケースには適した動作です。

--assume-unchanged

git update-index --assume-unchanged

変更すべきではないファイルを無視します。検知した差分を無視するのではなく、Git管理下に置きつつも変更検知の対象外とします。対象外とする分、処理速度が向上します。

git reset --hard 適用時の違い

指定されたコミットに戻す動作であり、検知している差分についてはそのままとなります。

% git status

Changes not staged for commit:
  (use "git add <file>…" to update what will be committed)
  (use "git restore <file>…" to discard changes in working directory)
    modified:   a
    modified:   b

% git update-index --skip-worktree  a
% git update-index --assume-unchanged  b
% git reset --hard
% git update-index --no-skip-worktree  a
% git update-index --no-assume-unchanged  b
% git status<

Changes not staged for commit:
  (use "git add <file>…" to update what will be committed)
  (use "git restore <file>…" to discard changes in working directory)
    modified:   a

あとがき

普段は使わないコマンドだったため、動作確認も合わせて行ってみました。docker-composeにおける.envファイル等、--skip-worktreeは比較的身近に用途がありそうです。また、毎回git stashを使って対処しているケースで用途的に即していれば、非常に快適になると思います。