node_modulesをうっかりcommitしてしまった、.envファイルがリポジトリに入ってしまった、IDEの個人設定(.idea/・.vscode/)まで共有してしまった——「Gitに追跡されているファイルを管理から外したい」という場面は日常的に発生します。ファイルはローカルに残したままGitの追跡対象から外すのが正解で、単に.gitignoreに追記するだけでは解決しません。
この記事では、Gitでファイルを管理から外す方法を状況別に整理します。git rm --cachedによる「ファイルを残したまま追跡解除」、.gitignoreの正しい併用、一時的に変更を追跡させないskip-worktree/assume-unchanged、そして履歴から完全に削除したい場合の使い分けまで、実務で迷わない形で解説します。
この記事で学べること
- Git管理下の「tracked」と「untracked」の違いとステータス確認方法
git rm --cachedで「ファイルは残して追跡だけ外す」手順- 単一ファイル・ディレクトリ・glob・ignored済み全件の一括外し方
.gitignoreとgit rm --cachedの正しい併用順序- 一時的に変更を見せない
skip-worktree/assume-unchangedの使い分け - 他メンバーへの影響と、pull後に消えないための運用上の注意
- 履歴から完全削除が必要なケースの判断基準
まず押さえる:「Git管理」の3つの状態
「管理から外す」を正しく理解するには、Gitがファイルをどう扱っているかを整理すると迷いません。
ポイント:「管理から外す」とはtrackedからuntrackedに戻すことです。.gitignoreは「まだtrackedになっていないファイル」にしか効きません。一度git addされたファイルは、まずgit rm --cachedでtrackedから外してから.gitignoreで今後の追跡も防ぐ、という2段階が必要です。
中心コマンド:git rm –cached でファイルを残して追跡を外す
Gitの追跡対象から外すメインコマンドはgit rm --cachedです。--cachedを付けると作業ツリーのファイルは削除されず、Gitのindex(ステージング領域)からだけ外れます。次のcommitで「ファイルが削除された」という変更が記録され、以降リポジトリの追跡対象外になります。
# 単一ファイルを追跡から外す(ローカルには残る) git rm --cached config/secrets.env # ディレクトリを再帰的に外す git rm --cached -r node_modules/ # globパターンで一括(シェル展開を避けるため引用符で囲む) git rm --cached "*.log" git rm --cached -r "build/" # 追跡から外したことをcommit git commit -m "chore: secrets.env を追跡対象から除外" # プッシュしてチーム全体に反映 git push origin <branch>
git rm と git rm –cached の違い
削除しないのに「deleted:」表示になる
git rm --cached実行後のgit statusでは「deleted:」と表示されますが、これは「リポジトリから見て削除」という意味で、ローカルファイルは実在します。commit後に他メンバーがgit pullすると、その人のローカルからは削除されます(これは後述の落とし穴)。
.gitignore との正しい併用手順
git rm --cachedだけでは次にgit addしたら再び追跡対象に戻ります。再追跡を防ぐには.gitignoreに追記してから外すのが鉄則です。正しい手順は次のとおり。
# STEP 1: .gitignore に追加 echo "config/secrets.env" >> .gitignore echo ".env.local" >> .gitignore echo "*.log" >> .gitignore # STEP 2: 既に追跡されているファイルを index から外す git rm --cached config/secrets.env git rm --cached .env.local git rm --cached "*.log" # STEP 3: .gitignore と 削除 をまとめてcommit git add .gitignore git commit -m "chore: 機密・ログファイルを追跡対象から除外" # STEP 4: push git push origin <branch>
一気に「.gitignoreに合致する追跡ファイル全部」を外す
.gitignoreを後から整備した場合、既に追跡済みのファイルが無視ルールに合致していても追跡され続けることがあります。全件一括で外す場合は次のテクニックが便利です。
# .gitignoreに合致する既追跡ファイルをリストアップ git ls-files -i -c --exclude-standard # そのまま一括で追跡解除(macOS/Linux/Git Bash) git ls-files -z -i -c --exclude-standard | xargs -0 git rm --cached # commit git commit -m "chore: .gitignore に合致する追跡ファイルを一括除外" # リポジトリ丸ごと index を作り直す強力な手段(全ファイル再stage) git rm -r --cached . git add . git commit -m "chore: .gitignore を適用してindexを再構築"
注意:最後のgit rm -r --cached .+git add .は全ファイルのindexを作り直すため、改行コード・ファイルモード変更があると大量のdiffが出ることがあります。影響が不安な場合はまず対象ファイルだけ個別に処理してください。
「.gitignoreに追記したのに無視されない」問題の詳細は.gitignoreに追加しても既存ファイルが無視されないときの解決方法に原因と別解も含めて解説があります。
よくあるユースケース別の管理外し方
.env・config系の機密ファイル
# .gitignore に登録 echo ".env" >> .gitignore echo "config/secrets.yml" >> .gitignore # index から外す git rm --cached .env config/secrets.yml # commit git add .gitignore git commit -m "chore: 機密ファイルを追跡対象から除外"
警告:機密情報がパブリックリポジトリにpushされた場合、git rm --cachedは過去の履歴には残ります。漏洩した認証情報は即rotate(無効化・再発行)してください。履歴からの完全削除は履歴に含まれる機密情報を完全に削除する方法を参照。
ビルド成果物(dist/・build/・node_modules/)
# .gitignore に追加 cat >> .gitignore << EOF node_modules/ dist/ build/ *.log .next/ EOF # index から一括除外 git rm -r --cached node_modules/ dist/ build/ .next/ git rm --cached "*.log" git add .gitignore git commit -m "chore: ビルド成果物を追跡対象から除外"
IDE・OS固有ファイル(.idea/・.vscode/・.DS_Store)
個人の開発環境ごとに異なるIDE設定やOS生成ファイルはグローバルgitignoreで管理すると、各リポジトリの.gitignoreを汚さずに済みます。
# グローバルgitignoreを設定 git config --global core.excludesfile ~/.gitignore_global # ファイルに記述 cat >> ~/.gitignore_global << EOF .DS_Store Thumbs.db .idea/ .vscode/ *.swp .vs/ EOF # 既に追跡されているファイルは個別リポジトリで --cached 除外 git rm --cached -r .vscode/ git commit -m "chore: IDE設定ファイルを追跡対象から除外"
ポイント:IDE設定を.idea/フォルダごと外すかは判断が分かれます。共有すべき設定(run configuration、コード規約)は追跡、個人用(workspace.xml、タスク履歴)は除外というハイブリッド運用が現実的です。JetBrains公式の推奨.gitignoreを参照するとバランスが取れます。
大きなバイナリ・メディアファイル
リポジトリが肥大化してきた大きなファイルは、単に追跡解除するだけでなくGit LFSへの移行も検討します。LFS移行については本記事の範囲外ですが、「動画・画像・デザインデータ・ビルド済みバイナリ」はLFS対象の代表例です。
一時的に変更を追跡させない:skip-worktree と assume-unchanged
「ファイルはリポジトリに残したいが、自分のローカルだけ設定を変えて追跡させたくない」という特殊ケースにはgit update-indexの2オプションが使えます。追跡解除ではなく「追跡中だけど差分を見せない」という特殊な運用です。
# ローカルの変更を追跡させない(意図的に別設定を使いたい場合) git update-index --skip-worktree config/local-override.yml # skip-worktree を解除(再度追跡を戻す) git update-index --no-skip-worktree config/local-override.yml # skip-worktree指定ファイルを確認(先頭がSまたはsの行) git ls-files -v | grep "^[Ss]"
# パフォーマンス目的:「このファイルは変わらない」とGitに伝える git update-index --assume-unchanged config/large-static.json # 解除 git update-index --no-assume-unchanged config/large-static.json # assume-unchanged指定ファイルを確認(先頭が小文字hの行) git ls-files -v | grep "^h "
skip-worktree と assume-unchanged の違い
- skip-worktree:「意図的に差分を追跡しない」宣言。pull/checkout時も設定が優先される
- assume-unchanged:「変わらない前提」のパフォーマンス最適化。Gitが書き換える場合がある
- 個人設定の上書きには
skip-worktreeが推奨、大量ファイルの高速化用途がassume-unchanged - どちらもローカル限定で、他メンバーには影響しない(.gitの
info/excludeと同じ扱い)
注意:これらは本来の「管理から外す」とは違い、リポジトリには残したままローカルの挙動だけ変える特殊機能です。本当はconfig.example.ymlとconfig.ymlを分離し、前者だけ追跡する設計にするのが最も健全です。
他メンバーへの影響と安全な運用
git rm --cachedはリポジトリ上で「ファイル削除」として記録されるため、pull した他メンバーのローカルからはそのファイルが消えます。これが最大の落とし穴です。
# あなたがpushした時点から、プルする人に影響 # 他メンバー側で以下が起きる: # - .env が手元から消える(ローカルで復元が必要) # - node_modules/ が消える(npm ci で再インストール必要) # - IDE設定が消える(.vscode/ 等を再設定) # 他メンバーがpull後に実行すべきコマンドの例 # (機密・環境ファイルの復元) cp .env.example .env # あるいは vault から再取得 # (依存再インストール) npm install # or npm ci
安全な運用フロー
- 他メンバーに事前通知(Slack・PR descriptionで必ず周知)
.env.example/config.example.ymlのようにテンプレートを追加- READMEやCONTRIBUTINGに「初回セットアップ手順」を明記
- PRで変更内容を確認してもらう(自分一人でmainに直接pushしない)
- CIを運用している場合は「追跡外になったファイル」がビルドに必要でないか確認
履歴からも完全に削除したい場合
git rm --cachedは今後の追跡を止めるだけで、過去のコミットに含まれる内容は履歴に残り続けます。git log -pや古いクローンから参照可能です。
重要:履歴書き換えは全メンバーの再cloneが必要な破壊的操作です。実行前に必ずチームに周知し、進行中の作業を退避してもらってください。詳しい手順は履歴に含まれる機密情報を完全に削除する方法を参照。
誤って管理から外したときの復旧
git rm --cachedの commit前・push前なら簡単に戻せます。
# commit前:index を元に戻す git restore --staged <file> # あるいは旧構文 git reset HEAD <file> # commit済みだが未push:1つ前に戻す git reset --soft HEAD~1 # push済み:revertで打ち消し git revert <untrack-commit-SHA> git push origin <branch> # 特定ファイルだけ復元したい(過去コミットから取り出す) git checkout HEAD~1 -- path/to/file git commit -m "restore: path/to/file の追跡を復元"
ファイル復元の詳細は消したファイルを戻す方法、commit取り消しはコミットの取り消し方を参照。
やってはいけない落とし穴
.gitignoreに追記するだけで解決すると思う
.gitignoreはすでに追跡されているファイルには効きません。既にtrackedになったファイルはgit rm --cachedで一度indexから外してからignoreすることで初めて無視されます。これを知らずに.gitignoreだけ更新して「変更が反映されない」と悩むのはGit初心者の王道ミスです。
–cached を付け忘れる
git rm <file>(--cachedなし)はファイルごとローカルから削除します。大事な設定ファイルが消えてから「あれ?」となる事故が多発します。Git管理から外すだけなら必ず--cachedを付ける習慣を付けましょう。削除された場合でも未pushならgit restore <file>で戻せます。
他メンバーのローカルが消えることを忘れる
git rm --cachedをcommit/pushすると、他メンバーがgit pullした瞬間にそのファイルがローカルから消えます。.envやIDE設定など個人ファイルを消されて作業が止まる事故が起きます。PR descriptionや通知で事前アナウンス+.env.exampleのようなテンプレートファイル用意がセットです。
機密情報をrm –cachedで消したつもりで安心する
既に説明したとおり、履歴には残ります。APIキーやパスワードがpushされてしまった場合は必ずrotate→filter-repoの順で対応します。履歴から消えても、GitHub等は一度公開された内容をキャッシュしている可能性があるため、「漏洩したものは取り戻せない」前提で動きましょう。
globパターンを引用符なしで指定してシェル展開される
git rm --cached *.logとクォートなしで書くと、シェルが先に*.logを現存ファイル名に展開してからgit rmに渡るため、将来追加される*.logには適用されません。Gitに解釈させたいパターンは必ずダブルクォートで囲みましょう:git rm --cached "*.log"。
よくある質問
git rm --cached、今後も追跡しないよう.gitignoreに追記、この組み合わせが正解。新規ファイルで一度もaddしていないなら.gitignoreだけで十分です。git rm(–cached忘れ)でファイルを消したgit restore <file>で復元できます。commit済みならgit checkout HEAD~1 -- <file>で前のコミットから取り出せます。詳しくは消したファイルを戻す方法を参照。git rm --cached -r path/to/dir/で再帰的に外せます。ディレクトリは追跡対象ではなく「その中のファイル群」が追跡されているため、-r(再帰)が必須です。git filter-repoで可能ですが、全メンバー再clone必須です。パブリックリポジトリの場合、既に自動収集されている前提で動くのが安全です。--cachedは追跡自体を止めて他メンバーにも影響します。skip-worktreeは追跡は続けつつ自分のローカルだけ差分を見せない特殊設定です。「リポジトリに残すが個人設定で上書きしたい」ときはskip-worktree、「そもそも管理から外したい」なら--cachedです。git rm --cached <file>で一度indexから外してからcommitすれば無視されます。詳しくは.gitignoreに追加しても既存ファイルが無視されないときの解決方法を参照。関連記事
- 【Git】.gitignoreに追加しても既存ファイルが無視されないときの解決方法 — .gitignoreが効かない原因と対処
- 【Git】履歴に含まれる機密情報を完全に削除する方法 — filter-repoでの履歴クレンジング
- 【Git】add の取り消し方法 — 直前のaddをステージから戻す
- 【Git】untracked filesの解消方法 — untracked側の整理
- 【Git】消したファイルを戻す方法 — 誤って削除したファイルの復元
- 【Git】コミットの取り消し方 — rm –cached コミットの打ち消し
- 【Git】pushを取り消す方法 — push済みの追跡解除コミットへの対処
まとめ
- 「管理から外す」とはtrackedからuntrackedに戻すこと——
git rm --cachedが中心コマンド .gitignoreは「まだaddされていないファイル」にしか効かない- 正しい手順:.gitignore追記 → git rm –cached → commit → push
--cachedを忘れるとファイル自体が消える。必ず付ける- ディレクトリは
-r、globは引用符で囲む - 個人環境だけ差分を見せたくないなら
skip-worktree(特殊用途) - 他メンバーは
pullでファイルが消える——事前通知+テンプレート用意が必須 - 履歴からの完全削除は
filter-repo(機密情報・大容量バイナリのみ)
「Git管理から外す」は.gitignoreとgit rm --cachedを併用するだけ、と覚えれば迷いません。ファイルは残したいが追跡だけ外したいという意図を正確にコマンドへ翻訳できれば、.env漏洩事故やnode_modules誤commitといった典型的な事故を未然に防げます。チーム全員のローカルに影響する操作であることを意識し、事前通知+テンプレートファイルの用意+READMEへの手順記載までセットで運用しましょう。

