はじめに
Git を利用する開発現場では、特定のファイルを「一時的に無視」したいというニーズが頻繁に発生する。例えば、共有リポジトリ内の構成ファイルや、ビルドによって一時的に変更されるファイルが該当する。
Git にはこのようなケースに対応する2つの機能が存在する:
- assume-unchanged
- skip-worktree
本稿では、これら2つの機能の違い、使いどころ、内部挙動を技術的観点から明確に比較する。
1. 基本概念
1.1 assume-unchanged
git update-index --assume-unchanged <path>
このコマンドは、Git に対して「このファイルは今後変更されないものとして扱ってよい」というヒントを与える。
Git のステータストラッキングにおいて、変更検知の対象から外されるため、git status
でも変更が表示されなくなる。
ただし、実際には 変更されていても Git はそれに気づかない という点で注意が必要である。
1.2 skip-worktree
git update-index --skip-worktree <path>
こちらは「このファイルの内容はワークツリー上で編集されても、Git は一切関知しない」ことを意味する。
Git の挙動としては、ローカルの変更は完全に無視されるうえに、pull
などによってリモートの変更が存在しても、上書きされることがない。
この動作は、開発者ごとの設定差異(例:.env
, config.json
)など、ローカルで保持すべきカスタムファイルを扱う場面に適している。
2. 比較表
特徴 | assume-unchanged |
skip-worktree |
---|---|---|
ステージング対象になるか | いいえ | いいえ |
git status で表示されるか |
表示されない | 表示されない |
git diff に出るか |
出ない | 出ない |
リモート変更で pull 時に上書きされるか |
上書きされる可能性あり | 上書きされない(安全) |
用途 | ビルド成果物、一時ファイルなど | 設定ファイルのローカル上書きなど |
フラグの優先度 | 低 | 高(競合時はこちらが効く) |
3. 内部挙動の違い
両者は Git の index に対して異なるフラグを設定している。
assume-unchanged
は「パフォーマンス最適化」の一環で設計されており、あくまで Git のチェックを省略することが目的。skip-worktree
は「意図的に作業ディレクトリで変更されるファイル」に対する処理として設計されており、追跡から除外することが目的。
git ls-files -v
上記コマンドで現在のフラグ状態を確認可能である。
プレフィックス | 意味 |
---|---|
H |
skip-worktree |
h |
assume-unchanged |
4. 両者を同時に使った場合
技術的には、assume-unchanged
と skip-worktree
の両方のフラグを同じファイルに対して設定することは可能である。
ただし、skip-worktree
のほうが優先されるため、assume-unchanged
を併用する意味は事実上ない。
5. 実用的な適用例
ケース1:自動生成ファイル(例:.min.js
, *.cache
)
→ assume-unchanged
が適している。
ローカルでのビルドで変更されるが、Git 上のトラッキングは不要な場合。
ケース2:開発者ごとのローカル設定(例:config.local.json
)
→ skip-worktree
を使用するべき。
Git 管理は維持しつつ、ローカルごとの差異を無視したい場合。
6. 注意点と運用上のリスク
- どちらのフラグも Git の状態を「隠蔽」するものであり、使い方を誤ると意図せぬデータ損失が発生する可能性がある
- 特にチーム開発では、ドキュメントで運用ルールを明示すべき
- CI/CD パイプラインや GitHub Actions がこれらのファイルに関与する場合、
.gitignore
との整合性にも注意する必要がある
おわりに
assume-unchanged
と skip-worktree
は見た目の挙動が似ているため混同されがちだが、目的と設計思想が異なる。
正しく理解し、目的に応じて使い分けることで、Git による開発フローをより安全かつ柔軟に構築できる。