「あっ、コミットメッセージ間違えた!」 「まだ含めたくないファイルまでコミットしちゃった!」 「このコミット、なかったことにしたい…」
大丈夫です。Gitでは、コミットの取り消しは日常的な操作です。git reset
コマンドを使えば、様々な方法でコミットを取り消せます。
この記事では、git resetの3つのモード(–soft、–mixed、–hard)の違いから、実際の使い分けまで、具体例を交えながら分かりやすく解説していきます。
git resetの基本:「時間を巻き戻す」コマンド

git resetは3つの領域に影響する
Gitには3つの重要な領域があります:
- 作業ディレクトリ:実際にファイルを編集している場所
- ステージングエリア:git addした変更が待機する場所
- リポジトリ(HEAD):git commitした履歴が保存される場所
git resetは、これらの領域をどこまで巻き戻すかを選べる強力なコマンドなんです。
実例:セーブポイントに戻るゲームのように
RPGゲームでセーブポイントに戻ることを想像してください。
- セーブデータだけ戻す(–soft)
- セーブデータと装備を戻す(–mixed)
- すべてを完全に戻す(–hard)
git resetも同じように、どこまで戻すかを選べます。
3つのresetモード:それぞれの特徴と使い所
1. git reset –soft:コミットだけ取り消す
特徴:
- コミットは取り消される
- ステージングエリアの状態は維持
- ファイルの変更も維持
使い所: コミットメッセージを間違えた時や、コミットをまとめ直したい時
実例:
# 直前のコミットを取り消す(変更はステージングエリアに残る)
git reset --soft HEAD~1
# 状態確認
git status
# 結果:変更がステージングされた状態で表示される(緑文字)
イメージ: 「コミットという行為だけをなかったことにする」という感じです。
2. git reset –mixed(デフォルト):コミットとステージングを取り消す
特徴:
- コミットは取り消される
- ステージングエリアもクリア
- ファイルの変更は維持
使い所: もう一度git addからやり直したい時
実例:
# 直前のコミットとステージングを取り消す
git reset HEAD~1
# または
git reset --mixed HEAD~1
# 状態確認
git status
# 結果:変更がステージングされていない状態で表示される(赤文字)
イメージ: 「コミットとgit addをなかったことにして、編集だけ残す」という感じです。
3. git reset –hard:すべてを取り消す(危険!)
特徴:
- コミットは取り消される
- ステージングエリアもクリア
- ファイルの変更も削除(完全に元に戻る)
使い所: 完全にやり直したい時(ただし慎重に!)
実例:
# 直前のコミットと全ての変更を取り消す
git reset --hard HEAD~1
# 状態確認
git status
# 結果:nothing to commit, working tree clean
⚠️ 警告: --hard
は変更内容を完全に削除します。実行前に本当に削除して良いか確認してください!
よく使う実践パターン
パターン1:直前のコミットメッセージを修正したい
方法A:amendを使う(簡単)
git commit --amend -m "新しいコミットメッセージ"
方法B:reset –softを使う
git reset --soft HEAD~1
git commit -m "新しいコミットメッセージ"
パターン2:2つのコミットを1つにまとめたい
# 2つ前まで戻す(変更はステージングに残る)
git reset --soft HEAD~2
# まとめて新しくコミット
git commit -m "機能Aの実装(2つのコミットをまとめた)"
パターン3:間違えてコミットしたファイルを除外したい
# コミットを取り消し(変更は作業ディレクトリに残る)
git reset HEAD~1
# 必要なファイルだけ選んでadd
git add 必要なファイル1.txt
git add 必要なファイル2.txt
# 再コミット
git commit -m "必要なファイルのみコミット"
パターン4:特定のコミットまで戻りたい
# コミットのハッシュ値を確認
git log --oneline
# 例:abc1234 最新のコミット
# def5678 1つ前のコミット
# ghi9012 2つ前のコミット
# 特定のコミットまで戻る
git reset --soft ghi9012
HEAD~とHEAD^の違い:いくつ前に戻る?

HEAD~n:n個前のコミット
HEAD~1
またはHEAD~
:1つ前HEAD~2
:2つ前HEAD~3
:3つ前
HEAD^:親コミット(マージの場合に違いが出る)
通常はHEAD~
と同じですが、マージコミットの場合:
HEAD^
:第1親(メインブランチ側)HEAD^2
:第2親(マージされたブランチ側)
実用的には: 普段はHEAD~数字
を使えば十分です。覚えやすいですしね。
安全にresetする:失敗しないための予防策
1. 現在の状態を確認してから実行
# コミット履歴を確認
git log --oneline -5
# 現在の変更状況を確認
git status
# 差分を確認
git diff
2. ブランチを作ってバックアップ
# 現在の状態をバックアップ
git branch backup-before-reset
# resetを実行
git reset --hard HEAD~1
# もし失敗したら
git checkout backup-before-reset
3. reflogで復旧可能
git resetで消してしまっても、実はGitは履歴を保持しています:
# 操作履歴を表示
git reflog
# 例:reset前の状態に戻す
git reset --hard HEAD@{1}
リモートにpush済みのコミットを取り消す場合
注意:他の人と共有しているブランチでは避ける
リモートにpush済みのコミットをresetする場合は、特に注意が必要です。
個人ブランチの場合:
# ローカルでreset
git reset --hard HEAD~1
# 強制push(-fオプション)
git push -f origin ブランチ名
⚠️ 警告: push -f
は他の人の作業を壊す可能性があります。チーム開発では必ず相談してから実行してください。
より安全な方法:revertを使う
共有ブランチでは、resetではなくrevertを使いましょう:
# コミットを打ち消す新しいコミットを作成
git revert HEAD
# 通常通りpush
git push origin ブランチ名
revertは「取り消しのコミット」を作るので、履歴が残り安全です。
トラブルシューティング
トラブル1:resetしたけど元に戻したい
解決方法:
# reflogで履歴確認
git reflog
# reset前の状態のハッシュを探す
# 例:abc1234 HEAD@{1}: reset: moving to HEAD~1
# 元に戻す
git reset --hard abc1234
トラブル2:「Cannot do a soft reset in the middle of a merge」エラー
原因: マージ中にresetしようとした
解決方法:
# マージを中断
git merge --abort
# その後resetを実行
git reset --soft HEAD~1
トラブル3:間違えて–hardしてしまった
解決方法:
# すぐに実行!(時間が経つと復旧困難)
git reflog
git reset --hard HEAD@{1}
もしステージングされていない変更を失った場合、IDEの「ローカル履歴」機能を確認してみてください。
resetとrevertの使い分け

resetを使うべき場合
- ローカルのみの変更
- 個人ブランチでの作業
- 履歴をきれいに保ちたい時
revertを使うべき場合
- リモートにpush済み
- チームで共有しているブランチ
- 履歴を残したい時
覚え方: 「公開前ならreset、公開後ならrevert」
まとめ:resetは強力な味方
git resetは、Gitを使いこなす上で欠かせないコマンドです。
覚えておくべき3つのポイント:
- –soft:コミットだけ取り消し(一番安全)
- –mixed:コミット+ステージング取り消し(デフォルト)
- –hard:全部取り消し(要注意!)
今すぐ使えるコマンド:
# コミットメッセージ修正
git commit --amend -m "新しいメッセージ"
# 直前のコミット取り消し(変更は残る)
git reset HEAD~1
# 完全に元に戻す(慎重に!)
git reset --hard HEAD~1
# 困ったら履歴確認
git reflog
最初は--soft
と--mixed
だけ使って、慣れてきたら--hard
を使うようにしましょう。そして、困ったらreflogがあることを思い出してください。
Gitは失敗に寛容なツールです。resetを恐れず、どんどん使って慣れていきましょう!
コメント