git reset の実践的な使い方
soft / mixed / hard の使い分けから、HEAD~ / HEAD^ / コミットID指定まで
非推奨
git resetによるコミットの取り消しは基本的に非推奨ですresetは履歴を書き換えるため、プッシュ済みのコミットに使うと force push が必要になりチーム全体に影響します。プッシュ済みのコミットを取り消す場合は、履歴を壊さないgit revertを使いましょう。resetの利用はプッシュ前のローカルコミットに限定してください。--hardは使わない--hardは未コミットの変更を完全に消します。一時的に不要な変更はgit stashで退避し、本当に不要だと確信してからgit stash dropで消すほうが安全です。詳しくは reset --hard で消した変更を復旧する を参照してください。
3つのモードの使い分け
--soft(ソフト)はコミットだけ取り消してステージはそのまま残します。
コミットメッセージを書き直したいときや、複数コミットを1つにまとめたいときに使います。
--mixed(ミックスド / デフォルト)はコミットとステージを戻し、変更は作業ディレクトリに残します。
git add からやり直したいときに便利です。
--hard(ハード)はすべてを破棄するので、作業内容を完全になかったことにしたいときだけ使います。
# コミットメッセージを書き直したい → --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~1HEAD~ と HEAD^ の違い
HEAD~1 は「1つ前のコミット」、HEAD~3 は「3つ前のコミット」です。
数字は世代を表します。
一方 HEAD^ は「親コミット」を指し、マージコミットで HEAD^2 と書くと「2番目の親(マージされた側)」になります。
実務では HEAD~ をほとんど使い、HEAD^ はマージコミットの親を指定するときだけ使います。
# 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 など「操作の履歴」を確認でき、間違えた場合の復旧先を見つけられます。
# コミットハッシュを確認
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 bugreset を安全に使うコツ
保険用ブランチを作ってから reset する
git branch backupで現在位置を記録しておけば、間違えてもgit reset --hard backupで元に戻せます。未コミットの変更は stash で退避
git stashで作業中の変更を保存してから reset すれば、作業内容が消えません。--hard で消しても reflog で救える
git reflogに操作履歴が残っており、約30日以内ならgit reset --hard <hash>で復旧できる可能性があります。プッシュ済みには reset を使わない
他の開発者に影響するため、
git revertで打ち消しコミットを作るほうが安全です。
# 保険をかけてから 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 してください。
# --hard で消してしまった場合の復旧
git reflog
# ghi9012 HEAD@{1}: commit: 大事な変更
git reset --hard ghi9012
# reset 自体を取り消す
git reset ORIG_HEAD
Git Ready