【Git】変更を元に戻す方法を初心者向けにわかりやすく解説
はじめに
ソフトウェア開発をするうえでGitは欠かせない存在です。
ですが、ファイルを編集してみたはいいものの「間違えて変更しちゃった」「前の状態に戻したい」という場面は意外と多いのではないでしょうか。
こうした状況に対処できないと、作業が進まずに困ってしまうかもしれません。
本記事では、Gitでの「変更を元に戻す」ための具体的な方法を取り上げます。
「コミット前に戻したい」「コミット後に履歴を残したまま変更を取り消したい」「一部分だけ取り消したい」など、実務で起こりがちなシチュエーションに対応できるよう解説します。
この記事を読むとわかること
- Gitで変更を取り消す方法の基本的な流れ
- 実務でよく使われるコマンド例と、その使い分け
- 操作を間違えないための注意点
- さまざまな取り消しパターンの具体例
変更を元に戻すために押さえておきたいGitの仕組み
まずは、Gitがどのようにファイルの変更を管理しているのかを簡単に整理してみましょう。
Gitには 作業ツリー (Working Tree) 、 ステージ (Staging Area) 、 リポジトリ (Repository) という3つの領域があります。
- 作業ツリー:実際に編集している作業用のディレクトリ
- ステージ:次にコミットしたい変更を登録する場所
- リポジトリ:コミット履歴を管理する場所
変更を元に戻す場合は、どの領域に対してアクションを起こすかがポイントです。
実務でも、コミット直後であればリポジトリからの取り消しになりますし、まだコミットしていなければ作業ツリーやステージだけをリセットすることになります。
なぜこの仕組みを理解する必要があるのか
たとえば、ファイルを修正してステージに上げた状態で「とりあえず直前のコミット内容に戻したい」という場合と、一度コミットしてから「このコミットをなかったことにしたい」という場合では、使うコマンドが異なります。
どの段階の変更を取り消したいのかを、まずははっきりさせておくと、操作を間違えにくくなります。
コミット前の変更を取り消す方法
実際の現場では、コミット前の変更を取り消すだけでもさまざまなケースがあります。
- ステージに上げる前の変更を取り消したい
- ステージに上げた内容を取り消したい
ここでは、それぞれの取り消し方を具体例とともに見ていきましょう。
ワークツリーでの変更を破棄する
作業ツリーにはまだステージされていない変更が含まれていることがあります。
もし「ファイルを編集したけど、やっぱり元に戻したい」という場合には、git restore(またはgit checkout)を使う方法があります。
# 例: 特定ファイルの変更を元に戻す git restore path/to/file
あるいは、変更したファイルが多数あるものの、特定のファイルだけ元に戻したいケースもあります。
その場合は上記のようにファイルパスを指定します。
このコマンドを実行すると、ステージに上がっていない作業ツリーの変更が取り消され、元の内容(直前のコミット時点)に戻ります。
ステージに上げた変更を取り消す
ファイルを変更してステージに上げた後で「やっぱりステージに上げた内容を取り消したい」と思った場合は、次のようにします。
# 例: ステージに上がっているファイルを取り消し、作業ツリーは元の状態のまま git restore --staged path/to/file
この操作では作業ツリーの状態は残り、ステージだけがクリアされます。
もし「作業ツリーもまとめて消して元に戻したい」という場合は、さらに上のコマンドと組み合わせることで両方を取り消すことが可能です。
git restore --staged path/to/file
git restore path/to/file
そうすれば、ステージと作業ツリーの変更がすべて取り消され、ファイルは直前のコミット状態に戻ります。
コミット後の変更を取り消す方法
次はコミット後に変更を取り消したい場合です。
この場合、リポジトリ内のコミット履歴に対して操作を行うことになるので、コマンドの効果や取り扱いに注意しましょう。
コミットを打ち消す場合(git revert)
git revertは、既に行ったコミットの内容を打ち消すためのコマンドです。
既存のコミット履歴を修正するのではなく、あくまで「打ち消し用のコミット」を新たに作るという仕組みです。
そのため、履歴を改ざんせずに「取り消し」を表現できます。
# 例: 直前のコミットを打ち消す git revert HEAD
複数のコミットをまとめて取り消したい場合は、打ち消したいコミットのハッシュを指定して何度か実行します。
実務では「履歴を改ざんしてしまうと困る」「チームメンバーにも変更履歴が分かるようにしたい」といった理由で、git revertを使うことが多いです。
コミットそのものをなかったことにしたい場合(git reset)
チーム開発では推奨される方法ではありませんが、ローカルで作業している場合などに「直前のコミットは要らないから、なかったことにしたい」という場面もあるかもしれません。
その場合は、git resetを使います。
# 例: 直前のコミットを取り消して、変更をステージにも残さない git reset --hard HEAD^
これを行うと、リポジトリのHEAD(直前のコミット)が一つ前に移動し、コミットを取り消した状態に強制的に戻します。
ただし、--hardを使うとステージや作業ツリーの変更内容も含めて取り消されるので、重要な変更が消えてしまわないように気を付けましょう。
ソフトリセットとハードリセットの違い
git resetには--soft
、--mixed
、--hard
など複数のオプションがあります。
- --soft:リポジトリだけを指定したコミットの状態に戻し、作業ツリーやステージは維持する
- --mixed(デフォルト):リポジトリを指定したコミットの状態に戻し、ステージの変更は破棄されるが作業ツリーは残る
- --hard:リポジトリ、ステージ、作業ツリーすべてを指定したコミットの状態に戻す
削除したくない変更がどこに残っているのかをよく確認し、オプションを選ぶ必要があります。
一部分だけ以前の状態に戻したい場合
複数のファイルを一気に編集してコミットしたものの、そのうち特定のファイルだけ前の状態に戻したいということがあります。
そういうときに使えるのが、git checkoutあるいはgit restoreでファイル単位で変更を戻す方法です。
ただし、既にコミットしてしまった内容を一部だけ変えたい場合は、新たにコミットを追加するか、git revertを部分的に行うなどの操作が必要になります。
実務での例:特定のファイルだけ取り消す
たとえば、機能Aと機能Bを同時に作業していたところ、機能Bの実装が不要になったというシチュエーションを考えてみましょう。
機能Bに関する変更がまだコミット前なら、git restore path/to/fileB
で簡単に戻せます。
もし、すでにコミットしてしまったなら、
- 機能Bを取り消すための修正を行う
- そのまま新規コミットとして記録する
あるいは - git revertで当該コミットを打ち消す
このように「どのファイルを、どのタイミングのコミット状態に戻したいか」に応じてコマンドを選ぶのが重要です。
作業中の変更を一時的に退避する方法(git stash)
ちょっと視点を変えて、git stashというコマンドも覚えておくと便利です。
これは「現在の変更を一時的に避難させて、リポジトリをクリーンな状態に戻す」ためのコマンドです。
誤ってファイルを変更してしまい、別の作業をしたいときに変更を捨てるのではなく、一時保管して後で再開できるようにします。
# 例: 現在の作業ツリーとステージの変更を一時退避 git stash # 例: 退避した変更の一覧を確認 git stash list # 例: 退避した変更を適用(stash@{0}を指す) git stash apply # 例: 退避した変更を適用しつつ、stashリストから削除 git stash pop
このように、一度stashに退避させておけば誤って変更を破棄するリスクを減らしつつ、元の状態に戻ることができます。
ただし、そのまま放置するとstashがたまって管理しにくくなることがあるため、定期的に必要のないstashを削除する習慣を持っておくと良いでしょう。
誤操作を防ぐための注意点
Gitで変更を元に戻す際、いくつか気を付けたいポイントがあります。
取り消したい変更が本当に不要かどうか、念入りに確認する
大事な作業を消してしまうと、復元が難しくなることもあります。
リモートリポジトリにpushした後でresetなどをすると、履歴が合わなくなる恐れがある
チーム開発の際は慎重に扱いましょう。履歴が他のメンバーと食い違うと衝突が起きやすくなります。
stashを使い過ぎると管理が煩雑になる
いつ、何をstashしたのかわからなくなることがあります。コミットかstashか、どちらが適切か見極めることが大切です。
コミット履歴を修正するコマンド(git reset --hardなど)は、基本的にチーム共有前のローカル環境で使うことが多いです。リモートとの履歴がずれるとトラブルの原因になりやすいので、使うタイミングには注意しましょう。
実務での活用シーン
たとえば、ウェブサイトの開発プロジェクトで、あるページのデザイン変更と機能追加を同時進行しているとします。
作業の途中で「デザイン変更は先にリリースしたいから、機能追加の変更は一旦取り消しておきたい」という場合には、stashやrestoreを使うことで不要な変更を捨てることなくリポジトリをクリーンな状態に戻せます。
一方、すでにコミットをしてしまった後で「やっぱりこのコミットが不要だった」ということが判明した場合には、revertで新たなコミットを作って取り消すことを検討するでしょう。
このように、どの変更をどの段階で取り消したいかによって使うコマンドを選ぶのが実務でのポイントです。
コマンド一覧表
ここで取り上げた主なコマンドを、簡単にまとめておきます。
コマンド | 目的 | 主なオプション |
---|---|---|
git restore | ワークツリーまたはステージの変更を取り消す | --staged |
git revert | 過去のコミットの変更を打ち消す | 取り消したいコミットのハッシュ |
git reset | コミットの履歴を指定した地点まで巻き戻す | --soft, --mixed, --hard |
git stash | 作業中の変更を一時退避する | apply, pop, list |
まとめて取り消す場合はgit resetやgit revertを検討し、部分的に取り消す場合はgit restoreを使うなど、状況に合わせて適切なコマンドを選ぶことで、後戻りしやすい柔軟な開発フローが実現できます。
まとめ
Gitで変更を元に戻す方法はさまざまありますが、いずれにしてもどの状態の変更を、どの段階に戻したいのかを明確にすることが大切です。
- コミット前なら、主に
git restore
でワークツリーやステージを取り消す - コミット後なら、
git revert
で打ち消しコミットを作るか、git reset
で履歴自体を巻き戻す - 作業を一時的に退避したいときは、
git stash
で安全に避難させる
これらを使い分ければ、誤った変更によるトラブルを大幅に減らせるでしょう。
特にチームで開発している場合、履歴の改ざんは慎重に取り扱う必要があります。
状況に応じて、どれが最適なのかを判断できるようになっておくと、スムーズな共同作業につながります。
この記事が、作業中の行き詰まりやコミットミスの解消に少しでもお役に立てば幸いです。