git rm --cached を使用して Git インデックスからファイルを削除する方法

GitBeginner
オンラインで実践に進む

はじめに

Git は、開発者がコードベースを効果的に管理するのに役立つ強力なバージョン管理システムです。Git でよくある作業の一つに、変更のステージングエリアであるインデックスからファイルを削除することがあります。このチュートリアルでは、ローカルファイルシステムからファイルを削除せずに、git rm --cached コマンドを使用して Git インデックスからファイルを削除する方法を説明します。

実践的な例で Git インデックスを理解する

Git インデックスは、ステージングエリアとも呼ばれ、Git バージョン管理システムにおける重要なコンポーネントです。これは、ワーキングディレクトリと Git リポジトリ間の仲介ストレージエリアとして機能します。ファイルに変更を加えた場合、Git はそれらの変更を自動的にコミットしません。代わりに、コミットする前に、変更を明示的にインデックスに追加する必要があります。

Git インデックスがどのように機能するかを理解するために、簡単な例を作成しましょう。

  1. まず、プロジェクト用の新しいディレクトリを作成し、Git リポジトリを初期化します。
mkdir git-index-demo
cd git-index-demo
git init

次のような出力が表示されるはずです。

Initialized empty Git repository in /home/labex/project/git-index-demo/.git/
  1. 次に、簡単なテキストファイルを作成します。
echo "Hello, Git!" > hello.txt
  1. リポジトリのステータスを確認します。
git status

hello.txt が追跡されていないことを示す出力が表示されるはずです。

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.txt

nothing added to commit but untracked files present (use "git add" to track)
  1. ファイルを Git インデックスに追加します。
git add hello.txt
  1. もう一度ステータスを確認します。
git status

これで、ファイルがコミットのためにステージングされていることが表示されるはずです。

On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   hello.txt

おめでとうございます!Git インデックスにファイルを加えたところです。Git が、git rm --cached <file> を使用してファイルのステージングを解除できることを教えていることに注意してください。これは、次のステップでまさに学習することです。

Git インデックスには、いくつかの利点があります。

  • 次のコミットに含める変更を、選択的に選択できます。
  • ファイルの特定の部分をステージングできます。
  • 次のコミットに何が含まれるかのプレビューを提供します。

次のステップでは、git rm --cached コマンドを使用して Git インデックスからファイルを削除する方法を学びます。

git rm --cached を使用してインデックスからファイルを削除する

Git インデックスにファイルが追加されたので、git rm --cached コマンドを使用してファイルを削除する方法を学びましょう。このコマンドは、ローカルファイルシステムからファイルを削除せずに、Git インデックス (ステージングエリア) からファイルを削除します。

前のステップの例を続けます。

  1. まだ git-index-demo ディレクトリにいることを確認してください。
cd ~/project/git-index-demo
  1. リポジトリの現在のステータスを確認しましょう。
git status

hello.txt がコミットのためにステージングされている (インデックス内) ことが表示されるはずです。

On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   hello.txt
  1. 次に、git rm --cached コマンドを使用して、Git インデックスからファイルを削除します。
git rm --cached hello.txt

次のような出力が表示されるはずです。

rm 'hello.txt'
  1. もう一度ステータスを確認します。
git status

ファイルが追跡されなくなったことがわかります。

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.txt

nothing added to commit but untracked files present (use "git add" to track)
  1. ファイルがローカルファイルシステムにまだ存在することを確認します。
ls -l

出力に hello.txt が表示されるはずです。

total 4
-rw-r--r-- 1 labex labex 11 [date] hello.txt

これは、git rm --cached が Git インデックスからのみファイルを削除し、ローカルファイルシステムからは削除しなかったことを確認します。

  1. インデックスから複数のファイルを削除する方法を理解するために、別のファイルを作成しましょう。
echo "Another file" > another.txt
git add another.txt
  1. ステータスを確認します。
git status

次のように表示されるはずです。

On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   another.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.txt
  1. 次に、hello.txt をインデックスに戻し、複数のファイルを削除する方法を見てみましょう。
git add hello.txt
git status

両方のファイルがインデックスに表示されるはずです。

On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   another.txt
        new file:   hello.txt
  1. 両方のファイルを一度にインデックスから削除するには、次のようにします。
git rm --cached hello.txt another.txt
  1. もう一度ステータスを確認します。
git status

両方のファイルが追跡されなくなっているはずです。

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        another.txt
        hello.txt

nothing added to commit but untracked files present (use "git add" to track)

git rm --cached コマンドは、次のような場合に特に役立ちます。

  • 誤ってファイルを Git インデックスに追加した場合
  • ファイルをシステムから削除せずに、ファイルの追跡を停止したい場合
  • ファイルパターンを .gitignore に追加しようとしているが、最初に既存のファイルをインデックスから削除する必要がある場合

次のステップでは、このコマンドの実用的なユースケースをいくつか探ります。

.gitignore を使用した実践的なユースケース

git rm --cached の最も一般的なユースケースの 1 つは、無視する必要があるファイルの追跡を停止する場合です。実践的な例でこれを見てみましょう。

ファイルの作成とコミット

まず、誤って無視すべきファイルをコミットしてしまった状況を作成しましょう。

  1. まだ git-index-demo ディレクトリにいることを確認してください。
cd ~/project/git-index-demo
  1. 既存のファイルをインデックスに追加しましょう。
git add hello.txt another.txt
  1. 次に、これらのファイルをコミットしましょう。
git commit -m "Initial commit"

コミットを確認する出力が表示されるはずです。

[master (root-commit) xxxxxxx] Initial commit
 2 files changed, 2 insertions(+)
 create mode 100644 another.txt
 create mode 100644 hello.txt
  1. 追跡したくない生成されたファイルをシミュレートするログファイルを作成します。
echo "Some log data" > application.log
  1. 誤ってこのログファイルを追加してコミットしましょう。
git add application.log
git commit -m "Add log file by mistake"

コミットを確認する出力が表示されるはずです。

[master xxxxxxx] Add log file by mistake
 1 file changed, 1 insertion(+)
 create mode 100644 application.log

.gitignore と git rm --cached の使用

次に、.gitignore ファイルを作成し、git rm --cached を使用して、この間違いを修正しましょう。

  1. すべての .log ファイルを無視するように指定する .gitignore ファイルを作成します。
echo "*.log" > .gitignore
  1. ステータスを確認します。
git status

次のように表示されるはずです。

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

nothing added to commit but untracked files present (use "git add" to track)

.gitignore ファイルに *.log パターンがあるにもかかわらず、application.log ファイルが変更されたものとしてリストされていないことに注意してください。これは、.gitignore が追跡されていないファイルがインデックスに追加されるのを防ぐだけであるためです。すでに追跡されているファイルは引き続き追跡されます。

  1. .gitignore ファイルを追加してコミットしましょう。
git add .gitignore
git commit -m "Add .gitignore file"
  1. 次に、ファイルシステムに保持したまま、ログファイルを Git インデックスから削除しましょう。
git rm --cached application.log

次のように表示されるはずです。

rm 'application.log'
  1. ステータスを確認します。
git status

次のように表示されるはずです。

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    application.log

これは、Git の追跡システムからのファイルの削除が、次のコミットに含まれることを示しています。

  1. この変更をコミットしましょう。
git commit -m "Stop tracking application.log"
  1. もう一度ステータスを確認します。
git status

次のように表示されるはずです。

On branch master
nothing to commit, working tree clean
  1. 次に、ファイルがまだファイルシステムに存在することを確認しましょう。
ls -l

application.log が他のファイルとともにまだ存在することが表示されるはずです。

total 16
-rw-r--r-- 1 labex labex 13 [date] another.txt
-rw-r--r-- 1 labex labex 13 [date] application.log
-rw-r--r-- 1 labex labex 6  [date] .gitignore
-rw-r--r-- 1 labex labex 11 [date] hello.txt
  1. ログファイルを変更して、Git が変更を追跡するかどうかを確認してみましょう。
echo "More log data" >> application.log
git status

次のように表示されるはずです。

On branch master
nothing to commit, working tree clean

ログファイルを変更したにもかかわらず、.gitignore パターンによりファイルが無視されるようになったため、Git は変更を検出しません。

これは、次のような、無視する必要があるファイルを誤ってコミットした場合に非常に一般的なワークフローです。

  • ビルド成果物
  • ログファイル
  • 機密情報を含む構成ファイル
  • 依存関係ディレクトリ (JavaScript プロジェクトの node_modules など)

.gitignore とともに git rm --cached を使用することで、次のことができます。

  1. 無視する必要があるファイルの追跡を停止する
  2. ファイルをローカルファイルシステムに保持する
  3. 今後、リポジトリに追加されないようにする

高度な例:機密情報の削除

git rm --cached のもう一つの重要なユースケースは、リポジトリの履歴から機密情報を削除することです。Git は変更を追跡するように設計されていますが、パスワード、API キー、その他の機密データを含むファイルを誤ってコミットしてしまうことがあります。

この状況をどのように処理するか見てみましょう。

  1. git-index-demo ディレクトリにいることを確認してください。
cd ~/project/git-index-demo
  1. 機密情報を含む設定ファイルをシミュレートするファイルを作成します。
echo "API_KEY=1234567890abcdef" > config.properties
echo "DATABASE_PASSWORD=supersecretpassword" >> config.properties
  1. このファイルを add および commit します。
git add config.properties
git commit -m "Add configuration file"
  1. 次に、機密情報をコミットしてしまい、ローカルコピーを保持したまま追跡から削除したいとします。
git rm --cached config.properties
  1. 実際の機密情報を含まないテンプレートファイルを作成します。
echo "API_KEY=your_api_key_here" > config.properties.template
echo "DATABASE_PASSWORD=your_password_here" >> config.properties.template
  1. テンプレートファイルを Git に add します。
git add config.properties.template
  1. 実際の config ファイルは無視し、テンプレートは追跡するように .gitignore ファイルを更新します。
echo "config.properties" >> .gitignore
  1. 更新された .gitignore ファイルを add し、これらの変更をコミットします。
git add .gitignore
git commit -m "Remove sensitive config from tracking, add template instead"
  1. リポジトリのステータスを確認しましょう。
git status

以下のように表示されるはずです。

On branch master
nothing to commit, working tree clean
  1. ファイルシステムに両方のファイルが存在することを確認します。
ls -l config*

以下のように表示されるはずです。

-rw-r--r-- 1 labex labex 60 [date] config.properties
-rw-r--r-- 1 labex labex 60 [date] config.properties.template
  1. どのファイルが追跡されているか確認します。
git ls-files | grep config

以下のみが表示されるはずです。

config.properties.template

このパターンはプロジェクトで一般的に使用されます。

  • 機密性の高い設定をバージョン管理から除外する
  • 他の貢献者が独自の設定ファイルを作成するためのテンプレートを提供する
  • 機密情報の誤ったコミットを防ぐ

git rm --cached はファイルを将来のコミットから削除しますが、Git の履歴からファイルを削除するわけではないことに注意してください。既にリモートリポジトリに機密情報をプッシュしている場合は、履歴から完全に削除するために追加の手順が必要になる場合があります。

実際のプロジェクトシナリオでは、以下を検討すると良いでしょう。

  • 漏洩した認証情報は直ちにローテーションする
  • 機密情報には設定ファイルではなく環境変数を使用する
  • 本番環境には専用のシークレット管理ソリューションを使用する

これで、git rm --cached コマンドの実用的なユースケースの探求は完了です!

まとめ

このチュートリアルでは、git rm --cached コマンドを使用して、ローカルファイルシステムからファイルを削除せずに、Git インデックスからファイルを削除する方法を学びました。ここで取り上げた内容は次のとおりです。

  • Git インデックス (ステージングエリア) と Git ワークフローにおけるその役割の理解
  • git rm --cached を使用して、インデックスから個々のファイルと複数のファイルを削除する
  • .gitignoregit rm --cached を統合して、無視する必要があるファイルの追跡を停止する
  • これらの概念を、誤ってコミットされたファイルの削除や機密情報の処理などの実践的なシナリオに適用する

これらのスキルは、クリーンな Git リポジトリを維持し、バージョン管理履歴にコミットされるものを適切に管理するために不可欠です。 git rm --cached を活用することで、ローカル作業ディレクトリをそのままにして、Git が追跡するファイルをより適切に制御できます。