Gitの変更取り消しはどう使い分ける?restore・reset・revertを実務目線で整理
Gitで変更を取り消したいとき、最初に押さえるべき結論はシンプルです。ファイルを元に戻すなら restore、コミットやステージの位置を動かすなら reset、共有済みコミットを打ち消すなら revert を使います。
迷いやすいのは、どれも「取り消す」ように見えることです。ただし、触る対象はそれぞれ違います。作業中のファイルなのか、ステージなのか、コミット履歴なのか。そこを切り分けると、コマンド選びはかなり楽になります。
git restore: 作業ツリーやステージしたファイルを戻すgit reset: ステージ解除や、ブランチ先頭のコミット位置を戻すgit revert: 既存コミットを打ち消す新しいコミットを作る- 共有ブランチで安全に戻したいなら、基本は
git revert git reset --hardは便利ですが、未保存の変更を消すので最後に使う
ここがポイント: 「何を戻したいか」を先に決めると、三つの違いは整理しやすくなります。ファイルなら
restore、履歴の付け替えならreset、公開済み履歴の打ち消しならrevertです。
まず確認したい前提環境
この記事は、Git 2.23以降を前提にしています。理由は git restore が Git 2.23 で追加されたからです。古い環境では、同じ目的でも git checkout や git reset を使う場面があります。
2026年4月25日時点で Git 公式ドキュメントを確認すると、git reset のマニュアルは 2.53.0、git revert は 2.54.0、git restore は 2.51.0 が案内されており、git restore はその後の版でも大きな説明変更はありません。実務で読むなら、まず自分の環境を確認しておくと混乱しません。
git --version
3コマンドの違いを最短でつかむ
この三つは、戻す対象が違います。
restore はファイルを戻す
git restore は、作業ツリーのファイル内容を戻したいときの基本コマンドです。--staged を付けると、ステージした内容も戻せます。
よくある場面は次のとおりです。
- 編集したけれど、まだコミットしていないファイルを元に戻したい
git addしたけれど、やはりステージを外したい- 特定コミット時点のファイルだけ取り出したい
reset はステージや履歴の位置を戻す
git reset は少し幅が広いコマンドです。軽い使い方なら「ステージ解除」、重い使い方なら「ブランチ先頭のコミット位置を動かす」役目です。
つまり、reset は便利ですが、履歴を書き換える方向に踏み込みやすいのが特徴です。
revert は履歴を消さずに取り消す
git revert は、過去コミットを消しません。代わりに、その変更を打ち消す新しいコミットを追加します。
そのため、すでに push した履歴や、他の人が見ている共有ブランチでは最も扱いやすい方法です。履歴が残るので、あとから「なぜ戻したのか」を追いやすい点も実務向きです。
迷ったときの選び方
最初にこの分岐で考えると判断しやすくなります。
- まだコミットしていないファイルを捨てたい:
git restore git addした内容だけ外したい:git restore --stagedまたはgit reset <file>- 直前コミットをやり直したいが変更内容は残したい:
git reset --soft HEAD~1 - ローカル履歴ごと戻したい:
git reset --hard <commit>ただし注意 - すでに共有したコミットを安全に打ち消したい:
git revert <commit>
git restore の基本的な使い方
restore は、「ファイルをどこから、どこへ戻すか」を意識すると分かりやすいコマンドです。
作業ツリーの変更を捨てる
app.js の未コミット変更を元に戻す例です。
git restore app.js
このコマンドは、通常はインデックスの内容を基準に作業ツリーを戻します。まだ git add していない編集を捨てたいときに向いています。
入力イメージ:
app.js を編集した
まだ git add はしていない
結果イメージ:
app.js が直前のステージ状態に戻る
ステージした変更を外す
git add app.js したあとで、ステージだけ外したいならこちらです。
git restore --staged app.js
これは「コミット対象から外す」操作です。ファイルの作業内容そのものは残ります。ここが git restore app.js と混同しやすい点です。
結果イメージ:
ステージ: 外れる
作業ツリーの編集内容: 残る
特定コミット時点のファイルを取り出す
3つ前のコミットの config.yml を使いたい場合です。
git restore --source HEAD~3 config.yml
この使い方は、ファイル単位で過去状態を確認したいときに便利です。コミット全体を巻き戻す必要がないので、調査や一部差し戻しに向いています。
git reset の基本的な使い方
reset はオプションごとに動きが変わります。初心者がまず覚えるなら、--soft、--mixed、--hard の違いを押さえるのが近道です。
--soft: コミットだけ戻し、変更は残す
git reset --soft HEAD~1
直前コミットを取り消しつつ、変更内容はステージされたまま残します。コミットメッセージを直したい、まとめ直したい、という場面で使いやすい形です。
--mixed: コミットを戻し、ステージも外す
git reset --mixed HEAD~1
--mixed は git reset の既定動作です。直前コミットをなかったことにしつつ、変更内容は作業ツリーに残します。
つまり、
- コミット: 戻る
- ステージ: 外れる
- ファイル変更: 残る
という状態になります。コミットし直す前提なら、この形がいちばん使いやすいことが多いです。
--hard: 履歴もファイル変更もまとめて戻す
git reset --hard HEAD~1
これは強力です。コミット、ステージ、作業ツリーをまとめて指定地点に合わせます。 未コミット変更も消えるため、取り返しがつかないケースがあります。
使う前に、少なくとも次は確認したいところです。
git statusで未保存変更が本当に不要か確認する- 共有ブランチでないか確認する
- 必要なら別ブランチを切るか
git stashで退避する
ステージ解除だけなら reset でもできる
git reset HEAD app.js
これは app.js のステージ解除です。Git 公式ドキュメントでも、この使い方は git restore --staged app.js とほぼ同じ位置づけです。
ただし、初心者には restore --staged のほうが意図が読み取りやすい場面が多いでしょう。
git revert の基本的な使い方
revert は、履歴を壊さずに打ち消したいときの本命です。
直前コミットを打ち消す
git revert HEAD
このコマンドを実行すると、直前コミットを逆向きに適用した新しいコミットが作られます。
入力イメージ:
A -- B -- C ← HEAD
git revert HEAD 実行後のイメージ:
A -- B -- C -- D ← HEAD
D は C を打ち消すコミット
この形なら履歴が残るため、すでに push 済みでも扱いやすいのが利点です。
共有ブランチで revert が向く理由
チーム開発で困るのは、履歴そのものを書き換えて他人の作業と衝突することです。reset でローカル履歴を戻してから強制 push すると、他メンバーの履歴とずれやすくなります。
その点 revert なら、
- 既存履歴を残せる
- 何を打ち消したか追跡しやすい
- 強制 push を避けやすい
というメリットがあります。
具体例で見る使い分け
ここでは、実務でよくある場面ごとに整理します。
例1: 編集したファイルを捨てたい
状況:
README.mdを編集した- まだ
git addしていない - やはり元に戻したい
使うコマンド:
git restore README.md
選ぶ理由は明快です。戻したい対象が「ファイル内容」だからです。
例2: git add したがコミット対象から外したい
状況:
git add src/app.jsした- でもまだ修正途中なのでコミットしたくない
使うコマンド:
git restore --staged src/app.js
ファイル編集は残したまま、ステージだけ外せます。
例3: 直前コミットを作り直したい
状況:
- コミットしたが、メッセージや含めるファイルを修正したい
- まだ共有していない
使うコマンド:
git reset --soft HEAD~1
変更内容を残したままコミットだけ戻せるので、まとめ直しがしやすくなります。
例4: 本番向けブランチに誤ったコミットを入れてしまった
状況:
- すでに
push済み - 他メンバーもその履歴を見ている
使うコマンド:
git revert <commit-id>
この場面で reset より revert を優先するのは、共有履歴を壊しにくいからです。
よくある失敗と対処
ここは初心者がつまずきやすいポイントです。
restore と reset を同じものだと思う
見た目は似ていますが、主役が違います。
restore: ファイルやステージ内容を戻すreset: HEAD やインデックスの位置を動かす
ステージ解除だけなら両方で近いことができますが、履歴を動かしたいかどうかで意味が変わります。
reset --hard を気軽に打つ
git reset --hard は便利ですが、ローカル変更をまとめて消します。まずは次の順で考えるのが安全です。
git statusで何が変わっているか確認する- 変更を残したいなら
git stashや別ブランチで退避する - 共有済みなら
revertを優先できないか考える
revert なのに作業ツリーが汚れていて失敗する
Git 公式ドキュメントでも、git revert は基本的にクリーンな作業ツリーを求めます。途中の変更が残っていると、意図しない競合や失敗につながります。
実行前に確認したい項目は次のとおりです。
git status- 途中変更のコミットまたは退避
- 対象コミットの特定
checkout との違いも押さえておく
Git 2.23以降は、git checkout が持っていた役割を git switch と git restore に分けて考える流れが分かりやすくなりました。
特に初心者にとっては、
- ブランチ移動は
git switch - ファイル復元は
git restore
と分けて覚えるほうが事故を減らしやすいです。古い記事では git checkout -- file.txt のような書き方が出てきますが、今の入門では git restore file.txt のほうが意図を読み取りやすいでしょう。
代替手段と使い分け
同じ「戻す」でも、周辺コマンドまで含めると選択肢は増えます。
git stash: いったん退避してから戻したいときに向くgit switch: ブランチの切り替え専用で、checkoutより意図が明確git checkout: 古い環境や既存記事ではまだ出てくるが、役割が広く初心者には誤解しやすい
実務では、「いきなり消す」より「いったん退避してから戻す」ほうが安全な場面も多いです。とくに reset --hard の前には、その一手間が効きます。
結局どれを選べばいいか
最後に、判断だけを短くまとめます。
- ファイルを元に戻したい:
git restore - ステージ解除や未共有コミットのやり直し:
git reset - 共有済みコミットを安全に打ち消したい:
git revert - 迷ったら
git statusを先に見る - 共有ブランチで履歴を書き換える操作は慎重に扱う
Gitの「取り消し」は、一つの万能コマンドで済ませるより、ファイル・ステージ・履歴のどこを触るのかで分けて考えるほうが失敗しにくくなります。次に触るときは、まず git status で現在地を見てから、restore、reset、revert のどれが対象に合っているかを選んでください。
