kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

Gitで追跡済みファイルを手元だけ追跡除外にするskip-worktreeを知った

他者のGit管理下のプロジェクトに対して、ローカルでのビルドでpackage.jsonが変わってしまうとか、.rbenvでのバージョンが微妙なのでそこはいじったとかな場面で、うっかりコミット候補に入ってしまわないよう注意深さを必要とするのが、地味に手間だった(怠惰)。

.gitignoreのローカル向けの.git/info/excludeは未コミットのものを最初から除外しておくものなので、すでに追跡されているもの向けではない。

サブコマンドで何かあったような気が……と探したところ、skip-worktreeサブコマンドを使うのが良いようだ(記事ありがとうございます)。

qiita.com

最初。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   package-lock.json
    modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")

このローカルだけ追跡から外す。

$ git update-index --skip-worktree package-lock.json package.json

外れた。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

スキップのフラグが付いている。

$ git ls-files -v | grep '^S'
S package-lock.json
S package.json

スキップを解除してみる。

$ git update-index --no-skip-worktree package-lock.json package.json

オカエリ。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   package-lock.json
    modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")

リポジトリ側からマージするときはどうなるのかなと参照記事の元記事のほうを見ると、スキップしていたファイルについては取り込まない、つまり更新しない。リポジトリの状況を定期的に監視して、スキップ対象ファイルに変更があったときには適宜スキップ解除する必要があるね。

qiita.com

昔からあるサブコマンドだけど、gitなんもわからんなぁ……(『入門git』はともかく濱野さんの『入門Git』にも載ってないので、その当時よりは新しいコマンドのようだ)。