【Git】git rmの取り消し方法|誤削除ファイルを復元する手順

【Git】git rmの取り消し方法|誤削除ファイルを復元する手順

PR Amazonのアソシエイトとして、ITナレッジライフは適格販売により収入を得ています。

記事の文字数:4,947

git rmコマンドで誤ってファイルやディレクトリを削除してしまったときの安全な復元方法を解説。ステージングの取り消しから作業ツリーのファイルを復旧させる具体的な手順まで、新人エンジニアが現場で焦りがちなトラブルの解決策をわかりやすく紹介します。

Gitユーザにお勧めの本 ↗

初心者向け

いちばんやさしいGit&GitHubの教本 第3版 人気講師が教えるバージョン管理&共有入門 「いちばんやさしい教本」シリーズ

難易度
実用性
読みやすさ

とにかく挫折しない丁寧な解説。チーム開発での基本的な流れを確実にマスターできます。

改訂2版 わかばちゃんと学ぶ Git使い方入門

難易度
実用性
読みやすさ

漫画形式で視覚的にイメージしやすい。Git特有の難しい用語も、物語を通して自然に理解できます。

独習Git

難易度
実用性
読みやすさ

コマンドの裏側で何が起きているかを丁寧に解説。プロとしてGitを使いこなすためのバイブルです。

「git rmを実行したら、必要なファイルまで一緒に消えてしまった……」「コミット前になんとか元に戻したいけれど、どうすればいいかわからない」と焦った経験はないでしょうか。

開発現場では、ファイル管理や不要なファイルの掃除の際にgit rmコマンドを誤って実行し、作業中のコードを消失させてしまうトラブルがよく発生します。

この記事を読むと、git rmによって削除されたファイルやステージング状態を安全に取り消し、元の状態に復元する具体的な手順がわかるようになります。

確認した環境

本記事の手順は以下の環境で動作を確認しています。

※本記事の手順は、すでに1回以上コミットが行われており、ファイルがGitのバージョン管理下に置かれているリポジトリを前提としています(初回コミット前で HEAD が存在しない状態では動作が異なります)。

git rmとは?ファイル削除とステージングの仕組み

git rmを実行するとどうなる?

git rmは、Gitの管理下にあるファイルを作業ツリー(ワークツリー)とインデックス(ステージングエリア)の両方から削除し、その削除を次回のコミットの対象として登録するコマンドです。

OSのコマンド(LinuxLinux [リナックス / ライナックス]オープンソースのOSカーネルのrmやWindowsのdel)でファイルを削除した場合、ファイルは作業ツリーから削除されますが、インデックスには削除前の情報が残ります。そのため、Gitは作業ツリーとインデックスの差分からファイルの削除を検出します(未ステージングの変更状態)。

一方、git rmを実行すると、作業ツリーからファイルを削除するとともに、インデックスにも削除が登録されます。そのため、通常は次回のコミットでファイルの削除が記録される状態(ステージングされた状態)になります。

git rm は、作業ツリーやインデックスに未コミットの変更があり、その内容が失われる可能性がある場合、通常は削除を拒否します。ただし、拒否される条件は変更の状態によって異なります。-f オプションを指定すると安全確認を強制的に無効化できるため、必要な変更を失わないよう注意してください。

コマンドの基本的な構文は以下の通りです。

Terminal window
git rm <ファイル名>

オプションを指定せずに実行すると、作業ツリー上のファイル自体が物理的に削除され、その削除がインデックスに登録されます。

git rm —cachedとの違い(追跡のみ解除する場合)

「Gitの管理からは外したい(追跡をやめたい)けれど、手元のファイルやディレクトリは手元に残しておきたい」という場面では、--cachedオプションを使用します。

Terminal window
git rm --cached <ファイル名>

このオプションを指定すると、インデックス(ステージングエリア)からファイルが削除され、作業ツリー上の実ファイルはそのまま残ります。コミットすると、そのファイルはリポジトリの管理対象から外れます。

例えば、ローカルの設定ファイルやログファイルなど、リポジトリに含めたくないファイルを誤ってバージョン管理に追加してしまった場合に役立ちます。なお、今後もGitの管理対象に含めたくないファイルは、必要に応じて .gitignore に記載してください。.gitignore に記載しない場合、次回以降に再び未追跡ファイル(Untracked files)として追加対象に検出されることがあります。

コマンド作業ツリー(実ファイル)インデックス(ステージング)主な用途
git rm <ファイル>削除される削除が記録されるファイル自体を完全に不要として削除したい場合
git rm --cached <ファイル>残る削除が記録される(追跡解除)設定ファイル等を手元に残し、Git管理からのみ外したい場合

git rmをコミット前に取り消してファイルを復元する方法

作業ツリーからファイルを削除し、まだコミットしていない段階であれば、Gitの機能を使って安全に元の状態へ復元できます。ここでは状況に応じた2つの手順を解説します。

ステージングを解除してからファイルを復元する手順

いきなりファイルを復元するのではなく、まずは削除のステージング(インデックスへの登録)を取り消してから段階的にファイルを復元したい場合や、git rm --cached によるステージングのみを取り消したい場合は、git restore コマンドを使用します。

ステップ1:現在のGitの状態を確認する

Terminal window
git status

実行例:

On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: src/app.js

ステップ2:ステージングを解除し、作業ツリーへファイルを復元する

削除のステージングを取り消した上で、作業ツリーへファイルを復元するには以下の2つのステップで実行します。

Terminal window
# 1. 削除のステージングを解除する(インデックスをHEADの状態に戻す)
git restore --staged src/app.js
# 2. 作業ツリーにファイルを復元する
git restore -- src/app.js

git restore --staged を実行すると、インデックスが HEAD の状態に戻り、ステージングされた削除が解除されます。ただし、作業ツリー上のファイルは変更されないため、git rm で削除されたファイルは自動的には復元されません。

そのため、続いて git restore -- src/app.js を実行し、インデックスに復元されたファイルの内容を作業ツリーへ反映します。

削除されたファイル自体を完全に元の状態に戻す手順(1コマンドで一括復旧)

git rmを実行すると、ファイルは作業ツリーだけでなくインデックスからも削除されます。そのため、インデックスに復元元となるファイルが存在しない状態では、単に git restore src/app.js を実行しても復元できません(通常の git restore はインデックスの内容を作業ツリーに反映するコマンドのため)。

この場合は、復元元として直前のコミット(HEAD)を指定し、インデックスと作業ツリーの両方を復元する方法が便利です。

ステップ1:作業ツリーとインデックスを直前のコミット状態に復元する

Terminal window
git restore --source=HEAD --staged --worktree -- src/app.js

各オプションの意味は以下の通りです。

オプション説明
--source=HEAD復元元として直前のコミット(HEAD)を指定する
--stagedインデックス(ステージングエリア)の削除を解除する
--worktree作業ツリーのファイルを復元する
--これ以降をファイルパスとして扱う

このコマンドにより、HEADに記録されているファイル内容が作業ツリーに復元され、同時にインデックスの削除指示も解除されます。

もしリポジトリ全体で誤って複数のファイルを削除してしまった場合は、パスに .(カレントディレクトリ)を指定することで一括復旧できます。

Terminal window
git restore --source=HEAD --staged --worktree -- .

[!WARNING] このコマンドは、指定したパスのインデックスと作業ツリーを HEAD の状態に復元します。そのため、対象ファイルに加えた未コミットの変更や、ステージング済みの変更も失われる可能性があります。 特に . を指定するとカレントディレクトリ以下の広い範囲が対象になります。実行前に git status や git diff、git diff --cached で変更内容を確認し、必要な変更があれば別途退避(git stash など)してください。

git restore が導入されたGit 2.23より前のバージョンでは、ファイルの復元に git checkout を使用できます。

以下のコマンドは、HEAD のファイル内容を作業ツリーとインデックスの両方に反映します。対象ファイルに未コミットの変更がある場合は、その変更が失われる可能性があるため注意してください。

Terminal window
git checkout HEAD -- src/app.js

すでにコミットしてしまった場合の対処法

git rmを実行した後に誤ってそのままgit commitまで完了させてしまった場合でも、履歴をたどることでファイルを復旧できます。

直前のコミットであればリセットで対応する

削除をコミットしたのが直前の1回だけであり、まだリモートリポジトリにプッシュしていない場合は、git resetを使用してコミットを取り消すことができます。

ステップ1:直前のコミット内容を確認する

git reset は直前のコミット全体を取り消します。対象のコミットに削除以外の変更も含まれていた場合、それらの変更もコミット履歴から外れてしまうため、事前にコミット内容を確認します。

Terminal window
git show HEAD

ステップ2:コミットを取り消してインデックスを直前の状態に戻す

Terminal window
git reset --mixed HEAD^

--mixed オプション(省略時のデフォルト動作)は、HEAD を1つ前のコミットに移動し、インデックスもそのコミットの状態に戻します。作業ツリーのファイルは変更されないため、削除されたファイルは自動的には復元されません。

※なお、git reset --soft HEAD^ を実行した場合は HEAD の位置だけが戻り、インデックスと作業ツリーは変更されないため、インデックスに削除のステージングが残ったままになります。そのため、ファイルを復元する目的では --mixed を使用するのが適切です。

ステップ3:インデックスから作業ツリーにファイルを復元する

インデックスが削除前の状態に戻っているため、以下のコマンドで作業ツリーにファイルを復元し、状態を確認します。

Terminal window
# 1. 作業ツリーにファイルを復元する
git restore -- src/app.js
# 2. 復元後の状態を確認する
git status

なお、git reset はローカルのコミット履歴を変更する操作です。共有ブランチで作業している場合は、実行前にブランチの状況も確認してください。

[!NOTE] すでにリモートリポジトリへプッシュしてしまったコミットを取り消す場合は、共有履歴を書き換えずに変更を打ち消す git revert が利用できます。直前のコミットが対象であれば git revert HEAD を実行します。過去のコミットを取り消したい場合は、対象のコミットハッシュを指定してください。

Terminal window
# 直前のコミットを取り消す場合
git revert HEAD
# 特定の過去コミット(例: abc1234)を取り消す場合
git revert abc1234

ただし、git revert はコミット全体の変更を打ち消します。削除以外の変更も含まれている場合は、その影響を確認してから実行してください。

過去のコミットから特定のファイルを復元する

すでに何世代も前のコミットで削除を確定させてしまっている場合や、特定のファイルだけを過去のバージョンから現在の作業ツリーに持ってくるには、ファイルの履歴を指定して復元します。

ステップ1:ファイルが存在していた過去のコミットハッシュを確認する

Terminal window
git log --oneline -- src/app.js

git log の結果から、復元したいファイルが実際に存在していたコミットを選択してください。削除を記録したコミットを指定してもそのコミットにはファイルが存在しないため、削除前のコミットを指定するのが基本です。

ステップ2:特定のコミットからファイルを指定して復元する

例えば、ファイルが存在していたコミットが abc1234 であれば、git restore コマンドでコミットハッシュを指定して復元します。

Terminal window
git restore --source=abc1234 -- src/app.js

このコマンドは、指定したコミット時点のファイル内容を作業ツリーに復元します。ただし、インデックス(ステージング)は更新されないため、復元したファイルをコミット対象にするには別途ステージングが必要です。

Terminal window
# 復元したファイルをステージングする
git add src/app.js
# 状態を確認する
git status

なお、復元と同時にインデックスも一緒に更新したい場合は、--staged と --worktree を併用します。

Terminal window
git restore --source=abc1234 --staged --worktree -- src/app.js

また、従来の git checkout コマンドを使用することも可能です。git checkout の場合は作業ツリーとインデックスの両方が同時に更新されます。

Terminal window
git checkout abc1234 -- src/app.js

まとめ:誤って削除しても落ち着いてgit restoreやresetを使おう

  • git rm は作業ツリーとインデックスの両方からファイルを削除し、削除をステージングするコマンドである
  • ファイルを手元に残してGitの追跡のみを解除したい場合は、git rm --cached を使用する
  • コミット前であれば、git restore --source=HEAD --staged --worktree -- <ファイル> で作業ツリーとインデックスを一括復旧できる
  • コミット直後であれば git reset --mixed HEAD^ の後に git restore で復旧できる(プッシュ済みの場合は git revert を推奨)
  • 過去のコミットから復元する際は、git restore --source=<コミット> 後に git add でステージングするか、--staged --worktree を指定する

現場で予期せぬファイル削除が発生しても、Gitの仕組みを正しく理解していれば慌てずに対応できます。操作を行う前には必ず git status で現在の状態を確認する習慣をつけましょう。


以上で本記事の解説を終わります。
よいITライフを!
ITナレッジライフ 運営者
この記事を書いた人

Z (ITナレッジライフ)

現役のITエンジニア。Linux、プログラミング、IT用語など、日々の業務で得た「痒いところに手が届く」技術情報を発信しています。

プロフィールと編集ポリシーを見る →

Gitユーザにお勧めの本 ↗

初心者向け

いちばんやさしいGit&GitHubの教本 第3版 人気講師が教えるバージョン管理&共有入門 「いちばんやさしい教本」シリーズ

難易度
実用性
読みやすさ

とにかく挫折しない丁寧な解説。チーム開発での基本的な流れを確実にマスターできます。

人気記事


記事を評価

Thanks!
目次
Scroll to Top