Git commit取り消し完全ガイド(push前) – 状況別の正しい取り消し方法

git

「間違ったファイルをコミットした!」 「コミットメッセージを間違えた…」 「このコミット、なかったことにしたい」 「まだpushしてないから今なら間に合う!」

Git を使っていて、こんな経験ありませんか?

大丈夫です。push前なら、どんなコミットも安全に取り消せます。しかも、状況に応じて最適な方法が複数あるんです。

今回は、push前のコミット取り消し方法を、ケース別に分かりやすく解説します。この記事を読めば、もうコミットミスも怖くありません!


スポンサーリンク

取り消し方法の全体像 – 3つの主要コマンド

方法の使い分け早見表

方法コマンドファイルの変更履歴使用場面
soft resetgit reset --soft HEAD~1残る(ステージング)消えるコミットだけやり直したい
mixed resetgit reset HEAD~1残る(作業ディレクトリ)消えるステージングからやり直したい
hard resetgit reset --hard HEAD~1消える消える完全になかったことにしたい
amendgit commit --amend上書き直前のコミットを修正したい
revertgit revert HEAD打ち消し用の変更残る履歴を残して取り消したい

ケース1:直前のコミットメッセージを修正したい

最も簡単な方法:–amend

状況:

# タイポしてコミットしてしまった
git commit -m "ログイン機能を実相"  # ×実相 → ○実装

解決方法:

# コミットメッセージを修正
git commit --amend -m "ログイン機能を実装"

# エディタを開いて編集したい場合
git commit --amend

ファイルも追加で修正したい場合:

# 忘れていたファイルを追加
git add forgotten_file.txt

# 前のコミットに含める
git commit --amend --no-edit  # メッセージは変更しない

ケース2:コミットを取り消して、変更は残したい

–soft オプション:ステージング状態に戻す

状況:

# 複数の機能を1つのコミットにしてしまった
git commit -m "ログイン機能とユーザー管理機能を追加"
# → 別々のコミットに分けたい!

解決方法:

# コミットを取り消し(変更はステージングに残る)
git reset --soft HEAD~1

# または
git reset --soft HEAD^

# 状態確認
git status
# Changes to be committed:
#   modified: login.js
#   modified: user.js

# 改めて個別にコミット
git reset HEAD user.js  # user.jsをアンステージ
git commit -m "ログイン機能を追加"
git add user.js
git commit -m "ユーザー管理機能を追加"

–mixed オプション(デフォルト):作業ディレクトリに戻す

状況:

# 間違ったファイルも含めてコミットした
git add .
git commit -m "機能追加"
# → ステージングからやり直したい

解決方法:

# コミットとステージングを取り消し(変更は作業ディレクトリに残る)
git reset HEAD~1
# または
git reset --mixed HEAD~1  # --mixedは省略可能

# 状態確認
git status
# Changes not staged for commit:
#   modified: file1.js
#   modified: file2.js

# 必要なファイルだけ選んで再度コミット
git add file1.js
git commit -m "file1.jsの機能追加"

ケース3:コミットも変更も完全に取り消したい

–hard オプション:すべてなかったことに

⚠️ 警告:変更内容が完全に失われます!

状況:

# 実験的な変更をコミットしたが、全部いらなくなった
git commit -m "実験的な機能"
# → 完全に削除したい

解決方法:

# 事前に確認(何が消えるか)
git diff HEAD~1

# コミットと変更を完全に削除
git reset --hard HEAD~1

# 状態確認
git status
# nothing to commit, working tree clean

安全策:事前にバックアップブランチを作成

# 念のためバックアップ
git branch backup-before-reset

# その後でreset
git reset --hard HEAD~1

# もし必要になったら
git checkout backup-before-reset

ケース4:複数のコミットを取り消したい

複数コミットの取り消し

状況:

# 最近の3つのコミットを取り消したい
git log --oneline
# abc1234 間違ったコミット3
# def5678 間違ったコミット2  
# ghi9012 間違ったコミット1
# jkl3456 正しいコミット ← ここまで戻りたい

解決方法:

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

# または特定のコミットまで戻る
git reset --soft jkl3456

# 相対指定も可能
git reset --soft HEAD^^^  # 3つ前

ケース5:特定のファイルだけ取り消したい

ファイル単位での取り消し

状況:

# 複数ファイルをコミットしたが、1つだけ取り消したい
git commit -m "複数ファイルの更新"
# → secret.txtは含めるべきじゃなかった

解決方法:

# コミットを取り消し
git reset --soft HEAD~1

# 特定ファイルをアンステージ
git reset HEAD secret.txt

# 残りを再コミット
git commit -m "複数ファイルの更新(secret.txt除く)"

実践的なシナリオと解決策

シナリオ1:間違ったブランチにコミット

# mainブランチにコミットしてしまった!
# (本当はfeatureブランチにしたかった)

# 解決策
# 1. コミットのハッシュを記録
git log --oneline -1
# abc1234 間違ったコミット

# 2. コミットを取り消し(変更は残す)
git reset --soft HEAD~1

# 3. 正しいブランチに切り替え
git checkout -b feature

# 4. 再度コミット
git commit -m "正しいブランチでコミット"

シナリオ2:デバッグコードが混入

# console.logが大量に含まれたままコミット

# 解決策
# 1. コミットを取り消し
git reset HEAD~1

# 2. デバッグコードを削除
# VSCodeなどで一括削除

# 3. 改めてコミット
git add .
git commit -m "機能追加(デバッグコード削除済み)"

シナリオ3:.gitignoreすべきファイルをコミット

# .envファイルをコミットしてしまった!

# 解決策
# 1. コミットを取り消し
git reset --soft HEAD~1

# 2. ファイルをアンステージ
git reset HEAD .env

# 3. .gitignoreに追加
echo ".env" >> .gitignore

# 4. .gitignoreをコミット
git add .gitignore
git commit -m ".gitignoreを更新"

# 5. 他の変更を再コミット
git add .
git commit -m "機能追加(.env除く)"

便利なエイリアスとスクリプト

よく使うコマンドのエイリアス設定

# ~/.gitconfigに追加

[alias]

# 直前のコミットを取り消し(変更は残す) uncommit = reset –soft HEAD~1 # 直前のコミットを取り消し(ステージングも) unstage = reset HEAD~1 # 直前のコミットメッセージを編集 reword = commit –amend # コミット前の状態を確認 last = log -1 HEAD # 取り消し可能な履歴を表示 undo-list = reflog

使用例:

git uncommit  # git reset --soft HEAD~1 と同じ
git reword    # git commit --amend と同じ

安全な取り消しスクリプト

safe_reset.sh:

#!/bin/bash
# 安全にリセットするスクリプト

echo "現在のコミット:"
git log --oneline -5

echo ""
read -p "何個前のコミットまで戻しますか? (1-5): " num

# バックアップブランチを作成
backup_branch="backup-$(date +%Y%m%d-%H%M%S)"
git branch $backup_branch
echo "バックアップブランチ作成: $backup_branch"

echo ""
echo "リセット方法を選択:"
echo "1) soft (変更を残す)"
echo "2) mixed (ステージング解除)"
echo "3) hard (すべて削除)"
read -p "選択 (1-3): " choice

case $choice in
    1) git reset --soft HEAD~$num ;;
    2) git reset HEAD~$num ;;
    3) 
        read -p "本当にすべて削除しますか? (yes/no): " confirm
        if [ "$confirm" = "yes" ]; then
            git reset --hard HEAD~$num
        fi
        ;;
esac

echo "完了!"
git status

reflogで取り消しを取り消す

間違えてresetしても大丈夫!

# しまった!間違ってhard resetした!

# 解決策:reflogで履歴を確認
git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~1
# def5678 HEAD@{1}: commit: 重要なコミット ← これを復活させたい

# 元に戻す
git reset --hard def5678

# または
git reset --hard HEAD@{1}

トラブルシューティング

Q: resetとrevertの違いは?

A: 履歴の扱いが違います

  • reset: 履歴から削除(なかったことに)
  • revert: 打ち消しコミットを作成(履歴は残る)

push前ならreset、push後ならrevertが基本です。

Q: どのresetオプションを使うべき?

A: 目的による

変更を残したい → --soft
ステージングをやり直したい → --mixed(デフォルト)
完全に消したい → --hard(注意!)

Q: 間違ってpushしてしまったら?

A: force pushが必要(要注意)

# ローカルで修正後
git push --force-with-lease origin branch-name

# ただし、共有ブランチでは絶対にやらない!

ベストプラクティス

コミット前の確認習慣

# コミット前に必ず確認
git status          # 何がステージングされているか
git diff --staged   # 変更内容の確認
git log --oneline -5  # 最近のコミット履歴

# エイリアスで簡単に
git config --global alias.check '!git status && git diff --staged'

コミットメッセージのテンプレート

# ~/.gitmessage.txtを作成
cat > ~/.gitmessage.txt << EOF
# タイプ: 簡潔な要約

# なぜこの変更が必要か?

# どのように実装したか?

# Types: feat, fix, docs, style, refactor, test, chore
EOF

# Gitに設定
git config --global commit.template ~/.gitmessage.txt

まとめ – もうコミットミスは怖くない!

push前のコミット取り消し方法、完全マスターできましたか?

覚えておくべき基本コマンド

git reset --soft HEAD~1 – コミットだけ取り消し
git reset HEAD~1 – ステージングも取り消し
git reset --hard HEAD~1 – すべて取り消し(注意)
git commit --amend – 直前のコミットを修正

黄金ルール

  1. push前なら何でも修正可能
  2. 迷ったら--softが最も安全
  3. --hardの前にバックアップ
  4. reflogがあれば復活可能

次のステップ

  • エイリアスを設定して効率化
  • コミット前の確認を習慣化
  • チームでルールを共有

これで、もうコミットミスを恐れる必要はありません。自信を持ってGitを使いこなしていきましょう!

コメント

タイトルとURLをコピーしました