Gitで何かを間違えたとき、git reset なのか git restore なのか git revert なのか。毎回検索して、出てきた記事のコマンドをそのまま打っている——という状態は、覚え方の問題であることが多いです。
3つの違いを「何ができるか」で覚えようとすると、おそらく覚えられません。できることが重なっているからです。公式マニュアル自身が、reset でも restore と同じことができる場合があると注記しています。重なっているものを機能の一覧で区別しようとすれば、境界が引けないのは当然です。
この記事では、3つを「何を動かすか」で読み替えます。参照したのは git の公式マニュアル——git(1)、git-revert、git-reset の3ページで、いずれも2026年10月14日に確認しました。git(1) のページには「git last updated in 2.56.0」と表示されており、変更履歴表によれば 2.56.0 は2026年9月28日です。以下の引用はその版のマニュアルに対するものです。
30秒で要点
- 公式マニュアルは3つを「何を対象にするか」で区別している。revert は打ち消す内容の新しいコミットを作るもの、restore は作業ツリーやindexのファイルを戻すものでブランチを更新しない、reset はブランチの先端を動かすものでコミット履歴を変える
- 「コミット履歴を変える」と明言されているのは reset だけ
- マニュアルが公開済みコミットについて警告しているのは、
git resetの例の1箇所。「すでに他の人に渡したコミットに対してはこれをするな」という形 - つまり危険なのはコマンドではなく状況。まだ誰にも渡していない手元の履歴なら、reset は普通に使える道具
git revertは作業ツリーがクリーンであることを要求する。一方git reset --hardは追跡されていないファイルを上書きすることがある。「とりあえず試す」の安全さは、名前の印象とは逆向きになりうる
公式マニュアルは、3つを機能ではなく対象で分けている
git(1) には "Reset, restore and revert" という節があり、「似た名前のコマンドが3つある」と切り出した上で、それぞれを1文で説明しています。逐語で引くと次のとおりです。
- git-revert: "is about making a new commit that reverts the changes made by other commits."
- git-restore: "is about restoring files in the working tree from either the index or another commit. This command does not update your branch."
- git-reset: "is about updating your branch, moving the tip in order to add or remove commits from the branch. This operation changes the commit history."
日本語に置くと、revert は「他のコミットが加えた変更を打ち消す、新しいコミットを作ること」。restore は「index(コミット前の変更を一時的に置く場所)か別のコミットから、作業ツリー(いま手元で編集しているファイルそのもの)のファイルを戻すこと」で、ブランチは更新しない。reset は「ブランチを更新すること」であり、ブランチの先端を動かしてコミットを足したり取り除いたりする。この操作はコミット履歴を変える。
3つの文を並べると、動かしている対象がきれいに分かれます。
表が収まらない場合は、横にスクロールできます
| コマンド | 動かすもの | 履歴への影響 |
|---|---|---|
| revert | コミット(新しく1つ積む) | 既存のコミットは消さない |
| restore | 作業ツリー(またはindex)のファイル | ブランチを更新しない |
| reset | ブランチの先端 | コミット履歴を変える |
ここで押さえたいのは、「コミット履歴を変える」と明言されているのは reset だけだという点です。なお、revert について「履歴を変えない」と書かれた記述はマニュアルにはありません。書けるのは「既存のコミットを消さず、打ち消すコミットを記録する」までです。
そして同じ節には、"git reset can also be used to restore the index, overlapping with git restore."——reset は index を戻すのにも使え、restore と重なる——という注記が続きます。これが冒頭で触れた重なりです。機能の一覧で覚えようとしても境界が引けないのは、マニュアル自身が重なりを認めているからです。
マニュアルは、目的別の案内も書いている
もうひとつ有用なのは、git-revert のページにある注記です。revert の説明の途中で、別の目的なら別のコマンドを見るように案内しています。
If you want to throw away all uncommitted changes in your working directory, you should see git-reset[1], particularly the --hard option. If you want to extract specific files as they were in another commit, you should see git-restore[1], specifically the --source option. Take care with these alternatives as both will discard uncommitted changes in your working directory.
作業ディレクトリの未コミットの変更をすべて捨てたいなら git reset(特に --hard)を見ること。別のコミットの時点の状態で特定のファイルを取り出したいなら git restore(特に --source)を見ること。そしてどちらも作業ディレクトリの未コミット変更を破棄するので注意すること——と書かれています。
目的を先に言葉にすれば、マニュアル自身が行き先を示してくれる構造になっています。迷うのは、目的が「間違えたので戻したい」という粒度で止まっているときです。何を戻したいのかまで言えると、選択肢は絞れます。
危険なのはコマンドではなく、状況のほう
「reset は危険だから使うな」と教わった人は多いはずです。この覚え方は、半分だけ合っています。
マニュアルの中で、公開済みのコミットについて警告しているのは git reset のページです。ただし場所は DESCRIPTION ではなく EXAMPLES 節の "Undo commits permanently" という1例で、git reset --hard HEAD~3 を示した上でこう書かれています。
The last three commits (HEAD, HEAD^, and HEAD~2) were bad and you do not want to ever see them again. Do not do this if you have already given these commits to somebody else.
直近3つのコミットが良くなく、二度と見たくない場合の例として挙げた上で、「すでにこれらのコミットを誰かに渡しているなら、これをするな」と付け加えています。原文では「not」が強調されています。
この警告の形に注目してください。禁じられているのはコマンドそのものではなく、「すでに他の人に渡したコミットに対して実行すること」です。条件節が付いています。
裏返すと、まだ誰にも渡していない手元のコミットに対しては、この警告は当てはまりません。ローカルのブランチで試行錯誤した履歴を整理する場面で reset を使うのは、マニュアルが止めている使い方ではないことになります。
履歴を動かす操作のコストは、技術的な難しさではありません。他の人がすでに持っている前提を、無効化してしまうところにあります。誰も持っていない履歴なら、無効化される前提もありません。
ただし、この警告が一般的な禁止としてマニュアルの冒頭に書かれているわけではない点は、そのまま伝えておきます。記述箇所は EXAMPLES の1例です。「公式が全面的に禁止している」という読み方は、原文より強くなります。
「安全そう」の感覚が、順番を間違えさせる
ここに、判断を狂わせやすい非対称があります。
git revert は、実行にあたって作業ツリーがクリーンであることを要求します。マニュアルの DESCRIPTION に "This requires your working tree to be clean (no modifications from the HEAD commit)." と明記されています。書きかけの変更が手元にあると、そもそも実行できません。
一方 git reset --hard は、指定したコミットの内容ですべてのファイルとディレクトリを上書きします。マニュアルは "may overwrite untracked files"——追跡されていないファイルを上書きすることがある——と書いており、さらに指定コミットに無い追跡ファイルは削除されるとしています。
つまり、まだGitに渡していないファイルまで巻き込みうるのは --hard の側です。ここでは --soft や --mixed といったオプションの細かい違いには踏み込みませんが、少なくとも --hard についてはこの記述を落とせません。「--hard は追跡しているファイルだけに影響する」という理解は、原文に反します。
読者がここで誤解しやすい理由は、名前の印象と実際の影響範囲が逆向きに感じられることにあります。「revert(元に戻す)」は穏当に聞こえ、「reset(初期化する)」は強そうに聞こえる。実際、強いのは reset の側です。ところが「とりあえず試してみる」ときに手が伸びやすいのは、穏当に聞こえるほうではなく、検索結果でよく見かけるほうです。
さらに revert は実行に前提条件があるぶん、条件を満たさなければエラーで止まります。止まるコマンドは、間違えても気づけます。止まらずに実行できてしまうコマンドのほうが、取り返しのつかなさは上です。
選ぶときに立てる、1本の問い
3つの違いを覚えるより先に、状況を確定させます。問いは1本です。
そのコミットを、すでに他の人が前提にしているか。
- 渡している(push済みで他の人が取得しうる)→ 履歴を動かさない選択肢から考える。打ち消したいなら revert が対象に入る
- 渡していない(手元のブランチだけ)→ 選択肢は広い。reset も普通の道具として使える
- そもそもコミットしていない(作業ツリーの話)→ 履歴の話ではない。restore の領域
順番が大事です。コマンド名から入ると、「reset は危険」のような一般論で止まります。状況から入ると、同じ reset でも使ってよい場面とそうでない場面が分かれます。
渡したかどうかを確かめる手順も、先に決めておけます。対象のブランチがリモートに push 済みかを確認する、共有ブランチなら触らないと決めておく、といった運用の問題であり、コマンドの知識とは別の層にあります。
確かなことと、この記事で扱わないこと
確かなこと: git 2.56.0 のマニュアルが3つのコマンドを対象の違いで説明していること。restore について「ブランチを更新しない」、reset について「コミット履歴を変える」と明記されていること。reset と restore の機能が重なると注記されていること。revert が作業ツリーのクリーンさを要求すること。reset --hard が追跡されていないファイルを上書きしうること。公開済みコミットへの警告が EXAMPLES の1例として書かれていること(いずれも2026年10月14日に確認)。
この記事で扱わないこと: --soft / --mixed / --hard の使い分けの詳細、rebase、reflog、stash。これらは独立した判断が必要なので、ここでは触れません。また git checkout も、マニュアルのこの節が3コマンドのみを扱っているため、並べて比較していません。マニュアルは更新されるので、重要な操作の前には使っている版のドキュメントを開き直してください。
手元で試せる、最小の検証
新しく覚えたことを、1回だけ確かめます。
手元のローカルブランチで、直前のコミットに対して履歴を動かさないものだけを選んで実行してみてください。つまり revert です。打ち消すコミットが1つ増えること、既存のコミットが消えていないことを git log で確認します。
その前に1行だけ挟みます。そのブランチが push 済みかを確認する。 この確認を先にやる癖がつけば、上の問いは自動的に立ちます。
reset を試すなら、使い捨てのブランチを作って、そこで実行します。消えて困るものが無い状態を作ってから試す——これは reset に限らず、取り返しのつかない操作を学ぶときの一般的な手順です。
迷ったときに戻る3つの問い
- 動かしたいのは、ブランチか、ファイルか、それとも新しいコミットを積むことか。 ここが決まれば、コマンドは絞れます
- そのコミットは、もう誰かに渡したか。 渡していれば選択肢は狭まり、渡していなければ広がります
- いま手元に、まだコミットしていない変更があるか。 あるなら、その扱いを先に決める必要があります
3つの問いはどれも、コマンドの知識ではなく状況の確認です。Gitの操作で迷う時間の多くは、コマンドを思い出せないことではなく、自分がどの状況にいるかを言葉にしていないことから来ています。
この記事はシリーズの一員として、既存の入門記事を前提にしています。コミットという単位そのものはコミットとは何か、ブランチの考え方はブランチとは何かとブランチ戦略の基本で扱っています。Gitを触るのが初めてならGitとは何かから読むほうが早いはずです。