「作業中のファイルをうっかり書き換えてしまったけれど、変更前の状態に戻すにはどうすればいいんだろう…」
「git add したファイルを元の状態に戻したいけれど、どのコマンドを使えば安全なのか迷ってしまう」
GitGit [ギット]ソースコードの変更履歴を管理する分散型バージョン管理システムを使って開発を進める中で、このようなファイルの変更取り消しに悩んだ経験はないでしょうか。誤ったコマンドを使ってしまうと、せっかく書いたコードが消えてしまうのではないかと不安になりますよね。
この記事では、Git 2.23で導入された git restore コマンドの使い方を徹底解説します。作業ディレクトリの変更破棄から、ステージングの解除、特定のコミットからのファイル復元まで、実務で役立つ意図した操作を安全に行う方法がわかるようになります。
git restoreとは?git checkoutとの違いを解説
git restoreの基本的な役割とメリット
Gitでファイルの状態を理解するうえでは、「HEAD(現在のHEADが指しているコミット)」「INDEXindex [インデックス]検索を高速化するためのデータ構造(ステージングエリア)」「WORKING TREE(作業ツリー)」の3つを意識すると分かりやすくなります。git restore は、作業ツリーやインデックスのファイルを、指定した復元元の内容に合わせて復元するためのコマンドです。
HEAD │ │ git restore --staged <file> ↓ INDEX │ │ git restore <file> ↓ WORKING TREE過去のコミットなどを復元元(--source)として指定することも可能です。
指定したコミット │ │ git restore --source=<commit> <file> ↓ WORKING TREEgit restore は、Gitの作業ディレクトリ(ワーキングツリー)やステージングエリア(インデックス)にあるファイルの変更を取り消すために設計されたコマンドです。
従来のGitでは、ファイルの変更破棄やブランチの切り替えなど、多くの役割が git checkout や git reset という一つのコマンドに集中していました。そのため、「今どの状態の操作をしているのか」がわかりにくく、誤操作によって意図しない変更を失うリスクがありました。
git restore は「ファイルの復元(復旧)」に特化しているため、コマンドの意図が明確になり、ファイルの復元操作を意図して実行できるというメリットがあります。Git 2.23では、従来の checkout の役割を、ブランチ操作の switch とファイル復元の restore に分ける形で導入されました。
git checkoutやgit resetとの使い分け
Git 2.23で git checkout からファイル復元の役割が分離され、現在の各コマンドの役割は以下の表のようになっています。
| 操作・目的 | コマンド | 主な用途 |
|---|---|---|
| ファイルの変更を破棄 | git restore <file> | 作業ツリーをindexの状態に戻す |
| ステージングを解除 | git restore --staged <file> | indexをHEADの状態に戻す |
| ブランチを切り替える | git switch <branch> | ブランチの移動 |
| コミット履歴を移動・変更する | git reset | HEAD・index・working treeの状態を移動・変更 |
このように、ファイルの復元やステージング解除には git restore を使用し、ブランチの操作には git switch を使用するのが近年のGitにおける標準的なプラクティスとなっています。
作業ディレクトリの変更を取り消す方法(ファイルの破棄)
ワーキングツリーの変更を直前の状態に戻す手順
作業ツリーの変更を破棄して、ステージングエリア(index)の状態に戻したい場合は、オプションなしで git restore を実行します。
例えば、app.js というファイルに誤った変更を加えた場合、以下のコマンドを実行します。
git restore app.jsgit restore app.js は、デフォルトではステージングエリア(インデックス)の内容を使って、app.js の作業ディレクトリ(ワーキングツリー)を復元します。ステージングされていない作業ツリーの変更は失われるため、実行前には本当に不要な変更であるかを確認してください。
特定のファイルだけを元に戻すコマンド例
複数のファイルを変更した場合、特定のファイルやディレクトリだけを指定して復元することができます。
# 単一のファイルを元に戻すgit restore index.html
# 複数ファイルを指定して元に戻すgit restore src/styles.css src/main.js
# カレントディレクトリ配下の作業ツリーの変更を、ステージングエリア(index)の状態に戻すgit restore .コマンドの実行時にファイルパスを指定することで、対象とするファイルを限定して復元できます。
ステージング(add済みの状態)を取り消す方法
—stagedオプションを使ったステージング解除
git add を実行してステージングエリア(インデックス)に追加したものの、コミットする前に「やっぱりこのファイルは一度ステージから外したい」という場合があります。このときは --staged オプションを使用します。
git restore --staged app.jsこのコマンドを実行すると、ステージングエリア(インデックス)をHEADの状態に戻します。作業ツリーの変更はそのまま残ります。
実行した際の出力例は以下のようになります。
$ git statusOn branch mainChanges to be committed: (use "git restore --staged <file>..." to unstage) modified: app.js
$ git restore --staged app.js
$ git statusOn branch mainChanges not staged for commit: (use "git add <file>..." to update what will be to commit) (use "git restore <file>..." to discard changes in working directory) modified: app.jsgit restore —stagedとgit resetの違い
従来、ステージングの解除には git reset HEAD <file> が一般的に使われていました。
git restore --staged <file> は、指定したファイルのインデックスをHEADの状態に戻す操作で、ファイル単位のステージング解除という点では git reset HEAD <file> と同等の結果になります。git restore --staged <file> は、ステージング解除という操作の意図をコマンド名から把握しやすい点がメリットです。
また、ステージングを解除した後に続けて作業ディレクトリの変更も完全に破棄したい場合は、以下のように2段階で実行します。
# ステージングを解除git restore --staged app.js
# 作業ディレクトリの変更も破棄git restore app.js特定コミットの状態までファイルを復元する方法
—sourceオプションで過去のバージョンに戻す
git restore は、直前のコミットだけでなく、過去の特定のコミットID(ハッシュ)やブランチを指定して、その時点のファイルの状態を復元することができます。これには --source オプションを使用します。
例えば、特定のファイルだけを2つ前のコミットの状態に戻したい場合は、以下のように実行します。
git restore --source=HEAD~2 src/config.jsonコミットハッシュを指定する場合の構文は以下の通りです。
git restore --source=a1b2c3d src/config.jsonこのコマンドを実行すると、指定したコミット時点の src/config.json が現在の作業ディレクトリに上書きされます。特定の機能だけを過去のバージョンに戻して検証したい場面などに役立ちます。なお、この操作によって新しいコミットが自動的に作成されるわけではありません。
実務でよくあるトラブルと注意点
変更内容が完全に消えるリスクへの対策
git restore で破棄した未コミットの変更は、通常のGit操作では元に戻せなくなるため、実行前に内容を確認してください。誤って実行してコードを失うトラブルを防ぐため、以下の対策を意識しておくと安全です。
-
git diffで変更内容を事前に確認する
復元コマンドを実行する前に、本当に捨てても問題ない変更かを確認します。作業ツリーの変更はgit diff、ステージング済みの変更はgit diff --cachedで確認できます。Terminal window # まだaddしていない変更(作業ツリーとインデックスの差分)git diff app.js# git add済みの変更(インデックスとHEADの差分)git diff --cached app.js -
作業を一時退避させる
git stashの活用
「変更をいったん取り消したいけれど、後でやっぱり見返すかもしれない」という場合は、変更を完全に破棄するのではなく、git stashを使って一時退避させるのが安全です。未追跡ファイルもstashに含めたい場合は-uオプションを付けます。Terminal window # 現在の変更を退避(未追跡ファイルも含める場合は git stash -u)git stash# 退避した変更の一覧確認git stash list# 必要に応じて退避した変更を復元git stash pop
まとめ:git restoreで安全にファイル操作を行おう
本記事では、Gitの変更を取り消すためのモダンなコマンド git restore について解説しました。
記事のポイントを以下にまとめます。
git restoreは、作業ツリーやステージングエリアのファイルを復元するためのコマンドである。- オプションなしで実行すると、作業ディレクトリの変更が破棄され、デフォルトではステージングエリア(インデックス)の状態に戻る。
--stagedオプションを使用すると、作業ツリーの変更を残したまま、ステージングを解除できる。--sourceオプションを使用することで、過去の特定のコミット時点からファイルを復元できる。- 誤って必要な変更を消去しないよう、実行前には
git diffやgit stashを活用する。
git switch や git restore によって、ブランチ操作とファイル復元操作をコマンドとして分けて扱えるようになりました。操作の目的を意識しながらコマンドを使い分けることで、意図しない操作を避けやすくなります。日々の開発フローに git restore を取り入れ、より効率的なバージョン管理を行いましょう。
以上で本記事の解説を終わります。
よいITライフを!
人気記事
- 1
- 2
- 3
- 4
- 5
とにかく挫折しない丁寧な解説。チーム開発での基本的な流れを確実にマスターできます。