コミット履歴を巻き戻すコマンド。--soft / --mixed / --hard で巻き戻しの深さを選べます。
git reset は、コミットを取り消して過去の状態に巻き戻すコマンドです。 タイムマシンのように「あの時点に戻りたい」というときに使います。
git reset の特徴は、巻き戻しの「深さ」を3段階で選べることです。 HEAD だけ戻すのか、Index も戻すのか、Working Directory まで全部戻すのか — この違いが--soft--mixed--hard の3つのモードです。
上のモード切り替えボタンで、それぞれの違いをステップごとに確認してみてください。
git reset は内部で最大3つの処理を順番に実行します。モードによって「どこで止まるか」が変わります。
| .git/refs/ (ブランチポインタ) | .git/index | Working Dir | |
|---|---|---|---|
| --soft | ポインタ移動 | 変更なし | 変更なし |
| --mixed | ポインタ移動 | リセット | 変更なし |
| --hard | ポインタ移動 | リセット | リセット |
--softコミットだけやり直したいとき。変更は staged のまま残るので、すぐに git commit できる。コミットメッセージを変えたい、複数コミットをまとめたいときに便利。--mixedデフォルトのモード。変更は Working Directory に残るが unstaged になる。git add からやり直したいときに使う。--hard完全に巻き戻す。変更はすべて消える。「この作業は全部なかったことにしたい」ときに使う。破壊的なので注意。git reset を理解するには、Git が管理する3つの領域を知る必要があります。 reset はこの3つの領域を「右から左」に順番にリセットしていきます。
git reset --soft [コミット]HEAD のみ移動。変更は staged のまま残るgit reset [コミット]--mixed がデフォルト。HEAD + Index をリセットgit reset --mixed [コミット]上と同じ。--mixed を明示的に指定git reset --hard [コミット]HEAD + Index + WD を全リセット(破壊的)git reset HEAD~1直前のコミットを1つ取り消す(HEAD~2 で2つ)git reset HEAD [ファイル]特定ファイルだけ unstage する(git add の取り消し)git reset は「参照(ポインタ)を動かす」コマンドであり、オブジェクトを削除するコマンドではありません。 --hard でも操作対象は .git/refs/、.git/index、Working Directory の3つだけで、.git/objects/ には一切触りません。
.git/objects/ は Git の全データ(ファイル内容・ディレクトリ構造・コミット履歴)を保存する場所です。 このストアは追記専用(append-only)で設計されており、blob、tree、commit は一度作られたら通常の Git 操作では削除されません。 これが Git の安全性の土台になっています。
bloba9f3b7eREADME.mdmain から参照ありblobe4f5a6bapp.tsどこからも参照なし(孤立)treet4e5f6aroot treecommit d4e5f6a から参照commitd4e5f6aAdd app.tsブランチ参照なし(孤立)commitc1a2b3cInitial commitmain から参照あり注意: --hard で消えた Working Directory の変更(コミットされていない編集内容)は .git/objects/ にも存在しないため、復元できません。復元できるのは、過去にコミットされたことがあるデータだけです。
--hard で消えたコミットは、実は .git/objects/ にまだ残っています。git reflog で過去の HEAD の移動履歴を確認し、消えたコミットのハッシュを見つけましょう。
ただし、コミットされていないファイルの変更(Working Directory の変更)は reflog でも復元できません。
他の人と共有しているブランチで reset すると、履歴の不一致が起きます。 push 済みのコミットを取り消すには git revert を使いましょう。 revert は「取り消すコミット」を新しいコミットとして追加するので、履歴が壊れません。
--mixed(デフォルト)で reset した後に「staged のままにしたかった」と気づいた場合は、git add . で再ステージすれば --soft と同じ状態になります。 逆に --soft で reset した後に unstage したい場合は git reset HEAD(ファイル指定なし)で Index だけリセットできます。