git addでステージングしたファイルを元に戻したいとき、状況に応じたコマンドを正しく選ばないと意図しない結果になる場合があります。特に初心者の方は「ファイル自体が消えてしまうのではないか」と不安になるかもしれませんが、適切なコマンドを使えば安全に取り消せます。
この記事では、git addの取り消しに使うコマンドを状況別に整理し、それぞれの使い方をサンプルコード付きで解説します。Git 2.23以降で登場したgit restore --stagedをはじめ、git resetやgit rm --cachedまで網羅しているため、どの状況でも対処できるようになるでしょう。
目次
- git addの取り消しに使うコマンド一覧
- git addをgit restore --stagedで取り消す方法
- ファイル指定でgit addを取り消す
- ディレクトリ単位・一括でgit addを取り消す
- git addをgit resetで取り消す方法
- ファイル指定でgit addをresetする
- 全部のgit addをresetする
- 初回コミット前のgit addを取り消す方法
- git rm --cachedで特定ファイルを取り消す
- git rm --cached -rで全ファイルを取り消す
- git addの取り消しで注意すべきポイント
- git restoreとgit restore --stagedの違い
- 複数回git addした場合の取り消し
- .envファイルを間違えてgit addした場合の対処
git addの取り消しに使うコマンド一覧
git addの取り消しに使うコマンドは、Gitのバージョンやリポジトリの状態によって異なります。以下の一覧表で、自分の状況に合ったコマンドをすぐに確認してください。
| 状況 | コマンド | 備考 |
|---|---|---|
| 特定ファイルの取り消し | git restore --staged ファイル名 |
Git 2.23以降で使用可能(※2.25以降は初回コミット前でも動作) |
| 現在のディレクトリ以下を一括取り消し | git restore --staged . |
Git 2.23以降で使用可能(※2.25以降は初回コミット前でも動作) |
| 特定ファイルの取り消し | git reset ファイル名 |
全バージョンで使用可能 |
| インデックス全体の取り消し | git reset |
全バージョンで使用可能 |
| 初回コミット前の取り消し | git rm --cached ファイル名 |
古いGitバージョンでも動作する確実な方法 |
| 初回コミット前の現在のディレクトリ以下を一括取り消し | git rm --cached -r . |
古いGitバージョンでも動作する確実な方法 |
git restore --stagedとgit reset ファイル名は、基本的にワーキングツリー(作業ディレクトリ上のファイル)の内容自体は変更せず、インデックス(ステージングエリア)だけを操作します。ただしgit rm --cachedは「追跡を外す変更」として次回コミットの対象になりうるため、単にaddを取り消したいだけならgit restore --stagedかgit reset ファイル名を優先すると安全です。
Git 2.23で導入されたgit restoreは、ワーキングツリーやインデックスの復元に役割を特化したコマンドです。git resetにはインデックス操作以外にHEADの移動を伴う使い方もあるため、役割の明確さから初心者にはgit restore --stagedを第一候補として案内しやすいでしょう。ただし、git resetが非推奨になったわけではなく、パス指定付きのgit resetは引き続き問題なく使用できます。
git addをgit restore --stagedで取り消す方法
git restoreはGit 2.23で導入された、ワーキングツリーやインデックスの復元を役割分担したコマンドです。--stagedオプションを付けるとインデックス側を復元でき、git addの取り消しに使えます。--staged使用時のデフォルトの復元元はHEAD(現在チェックアウトしているブランチの最新コミットを指すポインタ)であり、インデックスをHEADの状態に戻すことによってaddが取り消される仕組みです(HEADが存在しない初回コミット前は、空の状態に戻されます)。以下の2パターンを確認してください。
Restore specified paths in the working tree with some contents from a restore source. If a path is tracked but does not exist in the restore source, it will be removed to match the source.
ファイル指定でgit addを取り消す
特定の1ファイルだけをステージングから外したい場合は、git restore --stagedの引数にファイル名を指定します。最もよく使う基本的な操作で、間違えてaddしたファイルを1つだけ元に戻したいときに使用してください。
# 特定ファイルのgit addを取り消す
$ git restore --staged config.txt
# 複数ファイルを同時に取り消す場合はスペース区切りで指定
$ git restore --staged file1.txt file2.txt file3.txt
実行後にgit statusで確認すると、取り消したファイルが「Changes not staged for commit」の一覧に移動していることがわかります。ファイルの編集内容は保持されたままなので、改めてgit addすれば再度ステージングに戻せるでしょう。
なお、新規作成したファイル(まだ一度もコミットされていないファイル)をaddした後に取り消すと、そのファイルは「Untracked files」の状態に戻ります。既存ファイルの変更をaddして取り消した場合とはgit statusの表示が異なるため、この違いを把握しておくと混乱を防げます。
ディレクトリ単位・一括でgit addを取り消す
現在のディレクトリ以下をまとめてunstageしたい場合はドット(.)を、特定のディレクトリだけを対象にしたい場合はそのパスを指定します。同じディレクトリ基準でgit add .によりステージングした変更であれば、その範囲をまとめて取り消せるでしょう。
# 現在のディレクトリ以下を一括で取り消す
$ git restore --staged .
# 特定のディレクトリ配下だけを取り消す
$ git restore --staged src/
# 取り消し後の状態を確認
$ git status
On branch 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: index.html
modified: style.css
modified: app.js
全ファイルが「Changes not staged for commit」に移動していれば、取り消しは成功です。必要なファイルだけを選び直してgit addし直せばよいでしょう。ディレクトリを指定した場合は、サブディレクトリ内のファイルも含めてすべてがステージングから外れます。
前述の通り、--stagedオプション使用時のデフォルトの復元元はHEADです。ドット(.)やディレクトリパスはpathspec(パス仕様)として解釈されるため、リポジトリのルート以外から実行すると対象範囲が変わる点に注意してください。初心者のうちはリポジトリ内の相対パスで指定するのが安全です。
git addをgit resetで取り消す方法
git resetはGit 2.23より前から使用されてきたステージング取り消しの方法です。git resetには大きく分けて2種類あり、パス指定付き(git reset ファイル名やgit reset HEAD ファイル名)はHEADを動かさず、指定したファイルのインデックスのみを更新します。一方、パス指定なし(git resetやgit reset --hard HEAD~1など)は、インデックスの更新に加えて現在のブランチ(HEAD)自体を移動させるため、意味がまったく異なる点に注意してください。この章ではパス指定付きの使い方と、パス指定なしのgit reset(無引数)を解説します。
ファイル指定でgit addをresetする
特定のファイルをステージングから外す場合は、git reset ファイル名を実行します。パス指定付きのgit resetはインデックスだけを更新し、HEADの移動やワーキングツリーの変更は発生しません。
# 特定ファイルのgit addを取り消す
$ git reset config.txt
Unstaged changes after reset:
M config.txt
# HEADを明示した書き方(動作は同じ)
$ git reset HEAD config.txt
表示メッセージはGitのバージョンや環境によって異なる場合があるため、成否の確認はgit statusで行うのが確実です。取り消し対象のファイルが「Changes not staged for commit」に移動していれば成功しています。
公式ドキュメントでは、パス指定付きのgit resetについてgit addの逆操作であると明記されています。内部的には、指定したパスのインデックスをHEADの状態に書き戻す処理が行われます。
This means that git reset <pathspec> is the opposite of git add <pathspec>. This command is equivalent to git restore [--source=<tree-ish>] --staged <pathspec>...
全部のgit addをresetする
引数を何も指定せずにgit resetを実行すると、ステージングされた全ファイルが取り消されます。リポジトリのルートで実行するならgit restore --staged .に近い結果になりますが、厳密には対象範囲が異なります。
# 全ファイルのgit addを取り消す
$ git reset
Unstaged changes after reset:
M index.html
M style.css
M app.js
引数なしのgit resetはgit reset --mixed HEADと同義であり、インデックス全体をHEADの状態に戻します。git restore --staged .は現在のディレクトリ以下をpathspecとして指定しているため、サブディレクトリから実行した場合に対象範囲が変わります。
--mixedはインデックスのみをリセットするオプションであり、ワーキングツリーの変更はそのまま保持されます。--hardを付けるとワーキングツリーの変更もすべて破棄されるため、addの取り消しだけが目的の場合は絶対に--hardを付けないでください。
初回コミット前のgit addを取り消す方法
git init直後など、まだ一度もコミットを行っていないリポジトリでは、HEADがまだ存在しません(unborn branchと呼ばれる状態)。Git 2.25以降であればgit restore --stagedでも取り消し可能ですが、古いバージョンのGitではエラーになる場合があります。そのため、環境を問わず確実に動作する「インデックスから直接ファイルを削除する」コマンドとしてgit rm --cachedを紹介します。
git rm --cachedで特定ファイルを取り消す
git rm --cachedは、インデックスからファイルを直接削除するコマンドです。--cachedオプションを付けることによって、ワーキングツリーのファイルは削除せず、インデックスからの登録解除だけを行います。
# git init直後に間違えてaddしたファイルを取り消す
$ git rm --cached sample.txt
rm 'sample.txt'
$ git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
sample.txt
ファイルが「Untracked files」に戻っていれば成功です。--cachedを付け忘れるとワーキングツリーからもファイルが削除されてしまうため、必ずオプションの指定を確認してからコマンドを実行してください。
注意点として、git rm --cachedはすでに追跡中のファイルに対して使うと、「次回コミットでリポジトリからは削除する」変更としてインデックスに記録されます。そのため、コミット済みリポジトリで単にaddを取り消したいだけの場合にはgit restore --stagedやgit reset ファイル名を使うのが適切です。
Use the --cached option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.
git rm --cached -rで全ファイルを取り消す
ディレクトリごとまとめて取り消したい場合や、git add .で全ファイルを追加してしまった場合は、-r(recursive)オプションを付けて実行します。-rがないとディレクトリに対して実行できずエラーになります。
# 全ファイルのgit addを取り消す(初回コミット前)
$ git rm --cached -r .
# 特定ディレクトリ配下だけ取り消す
$ git rm --cached -r src/
ドット(.)を指定した場合、カレントディレクトリ以下にあるインデックス登録済みの全ファイルが対象になります。処理が完了すると、対象ファイルが「Untracked files」の一覧に表示されるようになるでしょう。
大量のファイルを一括で取り消す際は、処理完了後にgit statusで結果を確認し、意図しないファイルまで取り消していないかをチェックしてください。問題があれば再度git addで追加し直せます。
git addの取り消しで注意すべきポイント
git addの取り消し自体は比較的安全な操作ですが、コマンドの選択や使い方によっては予期しない結果になる場合があります。以下の3つは、前章までの基本操作とは異なる事故ポイントなので、事前に把握しておくとよいでしょう。
git restoreとgit restore --stagedの違い
git restoreは--stagedオプションの有無で動作がまったく異なります。git addの取り消し時に最も多い誤操作がこの混同なので、以下のコードで両者の違いを確認してください。
# ステージングだけを取り消す(ファイルの変更は残る)
$ git restore --staged file.txt
# ファイルの未ステージの変更を破棄する(インデックスの内容でワーキングツリーを上書きする)
$ git restore file.txt
--stagedを付けた場合は、インデックスをHEADの状態に復元するだけで、ワーキングツリーの編集内容はそのまま残ります。一方、--stagedなしで実行すると、今インデックスにある内容でワーキングツリーが上書きされ、未ステージの編集内容が失われます。通常は簡単には元に戻せないため、実行前に本当に破棄してよい変更か確認してください。
git statusを実行すると、Gitがどちらのコマンドを使うべきかを案内文で示してくれます。「unstage」という語を含む案内はステージングの取り消し、「discard changes」という語を含む案内はファイル変更の破棄を意味しています。ただし案内文の具体的な文言はGitのバージョンや状態で多少異なるため、意味で判断する習慣をつけましょう。
複数回git addした場合の取り消し
最後のコミット以降にgit addを2回以上実行した場合、git restore --stagedやgit reset ファイル名で取り消すと、すべてのaddがまとめてリセットされます。インデックスはHEAD基準に戻るため、「直前のadd 1回分だけをそのまま巻き戻す」操作には向きません。
# 1回目のgit add
$ git add file.txt
# ファイルをさらに編集した後に2回目のgit add
$ git add file.txt
# restore --stagedを実行すると1回目・2回目の両方が取り消される
$ git restore --staged file.txt
取り消し後のインデックスは、最後のコミット時点の状態に戻ります。hunk(変更の塊)単位で選択的にステージングを外したい場合は、git restore --staged -p ファイル名やgit reset -pのような対話的操作が使えます。これらのコマンドでは、変更を一つずつ確認しながらステージングに残すか外すかを選択できるため、部分的な取り消しが必要なときに便利です。
Interactively select hunks in the difference between the index and <tree-ish> (defaults to HEAD). The chosen hunks are applied in reverse to the index. This means that git reset -p is the opposite of git add -p.
— Git公式ドキュメント - git-reset
.envファイルを間違えてgit addした場合の対処
環境変数やAPIキーを含む.envファイルを誤ってaddしてしまった場合は、取り消しだけではなく.gitignoreへの追加まで一連の流れで対応する必要があります。コミット前であれば以下の手順で安全に対処できます。
# 1. まずgit addを取り消す
$ git restore --staged .env
# 2. .gitignoreに.envを追加する
$ echo ".env" >> .gitignore
# 3. .gitignoreをステージングしてコミットする
$ git add .gitignore
$ git commit -m ".gitignoreに.envを追加"
この手順により、.envをuntrackedに戻したうえで.gitignoreに追加できるため、通常の設定であれば以後のgit add .でも除外されるようになります。.gitignoreとは、Gitの追跡対象から除外するファイルやディレクトリのパターンを記述する設定ファイルのことです。なお、.gitignoreはuntrackedのファイルに対して有効であり、すでにGitが追跡中のファイルには効きません。
もしすでにコミットしてしまった場合は、git rm --cached .envを実行してインデックスから追跡を外したうえで、.gitignoreに追記してからコミットしてください。ただし、過去のコミット履歴にはファイルの内容が残っています。機密情報が含まれている場合は、リモートリポジトリへのプッシュ前に履歴の書き換えが必要です。git-filter-repoが現在の第一候補として推奨されており、GitHubの公式ドキュメントでもgit-filter-repoを使った手順が案内されています。必要に応じてBFG Repo-Cleanerも候補になるでしょう。
Install the latest release of the git-filter-repo tool. You need a version with the --sensitive-data-removal flag, meaning at least version 2.47.
※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。
ITやプログラミングに関するコラム
PythonをWebで実行する方法
共通テスト「情報Ⅰ」2年目で変わる、日本の教育と学び方
gitでブランチ(branch)を切り替える方法
git cloneでブランチを指定する方法
64GBのメモリが必要な人・不要な人の特徴
PCを再起動するコマンド一覧
CapsLock以外で大文字になる原因【Windows編】
パソコンで大文字になるのを解除する方法
面白いAIの活用事例を業界別に紹介
Gitでcommit(コミット)を取り消す方法
ITやプログラミングに関するニュース
サイボウズがkintone AIを正式提供、β版から約1年を経てクレジット制を導入
ロゼッタのラクヤクAIがCSRドラフト作成期間を90%以上短縮、従来4週間を約2日に
AI CROSSが不動産業界向け生成AI伴走支援を開始、アスコットの業務AI実装を実践サポート
日本情報クリエイトが「オーナー提案AIロボⅡ」売買査定を刷新、月1万円からW査定が回数無制限に
Wur株式会社がAI新規事業診断サービス「MVP事業診断レポート」をリリース、12の質問で事業構想を約10分で分析
バトンズがM&A専門家向け「AI概要書」β版を提供開始、企業概要書のドラフトを最速3分で自動生成
SCSKが観光DXサービス「Connexia」を開発、首里城公園でNFT活用の周遊促進が始動
Verdent AI発表、エンジニア不要でソフトウェアを構築する「AIエンジニアリングチーム」が登場
ゼネラルBREXAテクノロジーが外食・小売向けAIサービス「aimana」を開発、店長の意思決定をデータで支援
田中組がKencopa工程AIエージェント製品版を先行利用開始、建設現場の工程管理属人化を解消へ
