ガイド

git reset の実践的な使い方

soft / mixed / hard の使い分けから、HEAD~ / HEAD^ / コミットID指定まで

git reset の実践的な使い方 diagram

非推奨

  • git reset によるコミットの取り消しは基本的に非推奨です

    reset は履歴を書き換えるため、プッシュ済みのコミットに使うと force push が必要になりチーム全体に影響します。プッシュ済みのコミットを取り消す場合は、履歴を壊さない git revert を使いましょう。reset の利用はプッシュ前のローカルコミットに限定してください。

  • --hard は使わない

    --hard は未コミットの変更を完全に消します。一時的に不要な変更は git stash で退避し、本当に不要だと確信してから git stash drop で消すほうが安全です。詳しくは reset --hard で消した変更を復旧する を参照してください。

3つのモードの使い分け

--soft(ソフト)はコミットだけ取り消してステージはそのまま残します。

コミットメッセージを書き直したいときや、複数コミットを1つにまとめたいときに使います。

--mixed(ミックスド / デフォルト)はコミットとステージを戻し、変更は作業ディレクトリに残します。

git add からやり直したいときに便利です。

--hard(ハード)はすべてを破棄するので、作業内容を完全になかったことにしたいときだけ使います。

bash
# コミットメッセージを書き直したい → --soft
git reset --soft HEAD~1
git commit -m "新しいメッセージ"

# add からやり直したい → --mixed(デフォルト)
git reset HEAD~1
git add -p
git commit

# 全部捨てたい → --hard
git reset --hard HEAD~1

HEAD~ と HEAD^ の違い

HEAD~1 は「1つ前のコミット」、HEAD~3 は「3つ前のコミット」です。

数字は世代を表します。

一方 HEAD^ は「親コミット」を指し、マージコミットで HEAD^2 と書くと「2番目の親(マージされた側)」になります。

実務では HEAD~ をほとんど使い、HEAD^ はマージコミットの親を指定するときだけ使います。

bash
# 1つ前に戻す(最もよく使う)
git reset --soft HEAD~1

# 3つ前に戻す
git reset --soft HEAD~3

# マージコミットの2番目の親を確認
git log HEAD^2 --oneline

# HEAD~1 と HEAD^ は通常のコミットでは同じ意味
git log HEAD~1 --oneline
git log HEAD^ --oneline

コミットIDを指定して戻す

HEAD~ での相対指定が難しい場合は、コミットIDを直接指定できます。

git log --oneline でハッシュを確認し、そのハッシュを git reset に渡します。

また git reflog(リフログ)を使うと、reset や checkout など「操作の履歴」を確認でき、間違えた場合の復旧先を見つけられます。

bash
# コミットハッシュを確認
git log --oneline
# abc1234 Initial commit
# def5678 Add feature
# ghi9012 Fix bug

# 特定のコミットに戻す
git reset --soft abc1234

# 操作の履歴を確認(reflog)
git reflog
# abc1234 HEAD@{0}: reset: moving to abc1234
# ghi9012 HEAD@{1}: commit: Fix bug

reset を安全に使うコツ

  • 保険用ブランチを作ってから reset する

    git branch backup で現在位置を記録しておけば、間違えても git reset --hard backup で元に戻せます。

  • 未コミットの変更は stash で退避

    git stash で作業中の変更を保存してから reset すれば、作業内容が消えません。

  • --hard で消しても reflog で救える

    git reflog に操作履歴が残っており、約30日以内なら git reset --hard <hash> で復旧できる可能性があります。

  • プッシュ済みには reset を使わない

    他の開発者に影響するため、git revert で打ち消しコミットを作るほうが安全です。

bash
# 保険をかけてから reset する
git branch backup
git reset --hard HEAD~3

# stash で退避してから reset
git stash
git reset --mixed HEAD~1

# プッシュ済みなら revert を使う
git revert HEAD

よくある失敗と対処法

  • --hard で大事なコミットを消してしまった

    git reflog で消えたコミットのハッシュを探し、git reset --hard <hash> で戻せます。reflog は約30日分の操作履歴を保持しています。

  • reset 自体を間違えた

    git reset ORIG_HEAD で直前の reset を取り消せます。ORIG_HEAD は reset や merge の直前の位置を自動保存する特殊参照です。

  • 新しいコミットをしてしまってから気づいた

    reflog でさらに前の位置を探し、そこへ reset し直します。作業中の変更がある場合は事前に stash してください。

bash
# --hard で消してしまった場合の復旧
git reflog
# ghi9012 HEAD@{1}: commit: 大事な変更
git reset --hard ghi9012

# reset 自体を取り消す
git reset ORIG_HEAD

関連コマンド