ニッチワークス合同会社

← ブログ一覧

git reset を整理する

2026-03-11

#git


git reset は「コミットを取り消す」コマンド。オプションによって何をどこまで戻すかが変わる。

実行前 HEAD A B C ↓ git reset HEAD~1 実行後 HEAD A B C の変更の行き先 --soft → インデックス --mixed → 作業ディレクトリ --hard → 消える

オプション別の違い

ワーキングツリー インデックス リポジトリ --hard リセット リセット HEAD 移動 --mixed 変化なし リセット HEAD 移動 --soft 変化なし 変化なし HEAD 移動

--soft

コミットだけ取り消す。変更はインデックスに残ったまま。

実行前 HEAD A B C ↓ git reset --soft HEAD~1 実行後 HEAD A B インデックスに残る(staged) そのまま git commit できる状態 git add はやり直し不要

git reset --soft HEAD~1

直前のコミットを「なかったこと」にして、すぐ再コミットしたいときに使う。コミットメッセージを書き直したいときなど。

--mixed(デフォルト)

コミットを取り消し、インデックスも戻す。ワーキングツリーは変わらない。

実行前 HEAD A B C ↓ git reset --mixed HEAD~1 実行後 HEAD A B 作業ディレクトリに残る(unstaged) ファイルの変更は残っている git add からやり直せる

git reset HEAD~1
# または
git reset --mixed HEAD~1

「add をやり直したい」場面で使う。ファイルの変更自体は残る。

--hard

コミット・インデックス・ファイル内容、すべて戻す。

実行前 HEAD A B C ↓ git reset --hard HEAD~1 実行後 HEAD A B 消える(復元困難) ファイルもインデックスも元に戻る reflog で救出できる場合あり

git reset --hard HEAD~1

変更内容が完全に消える。やり直しが効かないので注意。

よく使うパターン

直前のコミットを修正したい

コミットメッセージだけ変えたいなら git commit --amend のほうがシンプル。 内容も変えたいなら:

git reset --soft HEAD~1
# 修正して
git add .
git commit -m "新しいメッセージ"

add を取り消したい

git reset HEAD ファイル名

リモートの状態に完全に戻したい

git reset --hard origin/main

ローカルの変更がすべて消える。

--hard を使う前に

消えたファイルは基本的に戻せない。ただし救出手段が2つある。

ORIG_HEAD で戻す(直後限定)

ORIG_HEAD は直前の reset/merge/rebase 前の HEAD を1つだけ記録している。reset した直後であれば使える。

git reset --hard ORIG_HEAD

注意点:reset を2回以上やると ORIG_HEAD は最後の操作の前しか覚えていない。

git reset --hard HEAD~2   # ORIG_HEAD = この前の位置
git reset --hard HEAD~1   # ORIG_HEAD が上書きされる
git reset --hard ORIG_HEAD  # HEAD~1 の前にしか戻れない

reflog で探して戻す

ORIG_HEAD が使えない場合は git reflog で履歴を探す。

git reflog
6c64c65 HEAD@{0}: reset: moving to HEAD~1
95f81ee HEAD@{1}: commit: D: 3行目を追加   ← 戻りたい位置

目的のハッシュが見つかったら指定して戻す。

git reset --hard 95f81ee
HEAD is now at 95f81ee D: 3行目を追加

reflog は一定期間(デフォルト90日)で消えるので過信しないこと。

演習:サンプルリポジトリで試す

用意してある。クローンして始める。

git clone https://github.com/smithshiro/git-practice
cd git-practice
git log --oneline
95f81ee D: 3行目を追加   ← HEAD
6c64c65 C: 2行目を追加
872b37a B: notes.txt を作成
35af1d0 A: 初期コミット (README)

この状態で D が HEAD。reset で B/C/D を使って練習できる。

--soft を試す

git reset --soft HEAD~1
git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   file.txt

C の変更が staged のまま残っている。cat file.txt すると3行目もある。

git log --oneline
6c64c65 C: 2行目を追加   ← HEAD
872b37a B: notes.txt を作成

元に戻す:

git reset --soft ORIG_HEAD

--mixed を試す

git reset --mixed HEAD~1
git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
        modified:   file.txt

ファイルの変更は残るが unstaged。git add からやり直せる。

元に戻す:

git reset --hard ORIG_HEAD

--hard を試す

git reset --hard HEAD~1
git status
On branch master
nothing to commit, working tree clean
cat file.txt
1行目
2行目

3行目は消えた。

元に戻す:

git reset --hard ORIG_HEAD
HEAD is now at 95f81ee D: 3行目を追加

ORIG_HEAD は直前のリセット前のコミットを記録している。リセットしてすぐなら git reset --hard ORIG_HEAD で戻せる。

だれでもLP — その思いつき、3分でページになる。