Git で過去のコミットに戻る完全ガイド|状況別の使い分けを徹底解説

「間違えてコミットしちゃった…!」
「このバグ、いつから入ってたんだろう?過去の状態を見たい」
「さっきの変更、なかったことにしたい…」

こんな経験、ありませんか?

大丈夫です。Gitには過去に戻るための強力な機能がたくさん用意されています。でも、git resetgit revertgit checkout…コマンドがいっぱいあって、「どれを使えばいいの?」と混乱してしまいますよね。

この記事では、状況に応じた最適な「戻り方」を、初心者の方にも分かりやすく解説します。読み終わる頃には、自信を持って過去のコミットに戻れるようになっているはずです!

スポンサーリンク
  1. 最初に知っておきたい重要なこと:「戻る」には種類がある
    1. 1. 履歴を書き換えて戻る(git reset)
    2. 2. 履歴を残したまま取り消す(git revert)
    3. 3. 一時的に過去を見る(git checkout / git switch)
  2. 使い分けの基本ルール:この質問で判断しよう
    1. プッシュしてない → git reset でOK
    2. プッシュ済み → git revert を使おう
    3. ただ確認したいだけ → git checkout / git switch
  3. git reset:タイムマシンで過去に戻る
    1. 3つのモードを理解しよう
    2. 実践例:直前のコミットをやり直す
    3. 特定のコミットに戻る方法
    4. HEAD~1、HEAD~2って何?
  4. git revert:安全に取り消す
    1. なぜ revert を使うの?
    2. 基本的な使い方
    3. メッセージなしで revert
    4. 特定のコミットを revert
    5. 複数のコミットを revert
    6. マージコミットの revert
    7. 実践例:プッシュ済みのバグを修正
  5. git checkout / git switch:過去を覗く
    1. 注意:Git 2.23以降の変更
    2. 過去のコミットを確認する
    3. 「detached HEAD」状態って何?
    4. 実践例:バグがいつ混入したか調査
    5. 過去の状態で新しいブランチを作る
  6. git restore:ファイルを復元する
    1. 特定のファイルだけを過去に戻す
    2. 特定のコミットからファイルを復元
    3. ステージングを取り消す
    4. 実践例:1つのファイルだけ過去に戻す
    5. 古い方法(git checkout)との比較
  7. 間違えた!取り消した resetを取り消す方法
    1. git reflog:Gitの履歴の履歴
    2. reset前の状態に戻る
    3. 注意:reflogには期限がある
  8. リモートにプッシュする方法
    1. revert の場合(簡単!)
    2. reset の場合(注意が必要!)
    3. より安全な強制プッシュ
  9. 状況別:どのコマンドを使うべき?
    1. ケース1:直前のコミットメッセージを修正したい
    2. ケース2:直前のコミットにファイルを追加したい
    3. ケース3:まだプッシュしてないコミットを取り消したい
    4. ケース4:プッシュ済みのコミットを取り消したい
    5. ケース5:過去のバージョンを確認したい
    6. ケース6:特定のファイルだけを過去に戻したい
    7. ケース7:間違えてファイルを削除してしまった
    8. ケース8:git addを取り消したい
  10. よくある質問(Q&A)
    1. Q1:reset と revert、どっちを使えばいい?
    2. Q2:reset –hard で消したファイル、復元できる?
    3. Q3:複数のコミットをまとめて取り消したい
    4. Q4:特定のコミットだけを取り消したい(間のコミットは残す)
    5. Q5:detached HEAD状態で作業しちゃった…
    6. Q6:リモートのコミットを強制的に元に戻したい
  11. まとめ:コマンド早見表
    1. 重要ポイント
  12. おわりに:失敗を恐れずに

最初に知っておきたい重要なこと:「戻る」には種類がある

実は、Gitで「過去に戻る」と言っても、やり方は大きく分けて3種類あります。

1. 履歴を書き換えて戻る(git reset)

タイムマシンのように過去に戻るイメージです。コミット自体を「なかったこと」にします。

例:日記を破って捨てる

メリット:履歴がスッキリ
デメリット:他の人と共有していると大混乱

2. 履歴を残したまま取り消す(git revert)

間違いを訂正する新しいページを追加するイメージです。「○○を取り消しました」という記録を残します。

例:日記に「昨日書いたことは間違いでした」と書く

メリット:安全で、チーム開発に最適
デメリット:履歴が増える

3. 一時的に過去を見る(git checkout / git switch)

タイムトラベルして見るだけのイメージです。過去を確認できますが、何も変更しません。

例:過去の日記を読み返すだけ

メリット:安全に過去を確認できる
デメリット:見るだけで、変更はできない

この違いを理解しておくことが、正しいコマンドを選ぶ第一歩です!

使い分けの基本ルール:この質問で判断しよう

どのコマンドを使うべきか迷ったら、この質問に答えてください:

「そのコミット、リモートにプッシュした?」

プッシュしてない → git reset でOK

まだ自分のパソコンにしかないコミットなら、git resetで履歴を書き換えても大丈夫です。

プッシュ済み → git revert を使おう

他の人も見ているコミットは、git revertで安全に取り消しましょう。

ただ確認したいだけ → git checkout / git switch

変更する予定がないなら、git checkoutgit switchで過去を覗くだけにしましょう。

それでは、それぞれのコマンドを詳しく見ていきます!

git reset:タイムマシンで過去に戻る

git resetは、ブランチのポインタを過去のコミットに移動させるコマンドです。

3つのモードを理解しよう

git resetには、3つのオプションがあります。どこまで戻すかが違います。

1. git reset –soft(やさしく戻る)

コミットだけを取り消します。 ファイルの変更は、ステージングされた状態で残ります。

git reset --soft HEAD~1

使う場面:

  • コミットメッセージを書き間違えた
  • ファイルを追加し忘れて、もう一度コミットし直したい

何が起こる:

  • コミット履歴 → 1つ前に戻る
  • ステージングエリア → 変更が残る(git addした状態)
  • ワーキングツリー → 変更が残る

2. git reset –mixed(中くらいに戻る)

コミットとステージングを取り消します。 ファイルの変更は残りますが、git add前の状態になります。

git reset --mixed HEAD~1

または(オプション省略でこれがデフォルト):

git reset HEAD~1

使う場面:

  • 間違えて大量のファイルをgit addしてしまった
  • コミットを分割して、もう一度git addからやり直したい

何が起こる:

  • コミット履歴 → 1つ前に戻る
  • ステージングエリア → 空になる
  • ワーキングツリー → 変更が残る

3. git reset –hard(完全に戻る)

すべてを取り消します。 コミットも、変更も、全部なかったことになります。

git reset --hard HEAD~1

⚠️ 超重要な注意:このコマンドは取り返しがつきません!

使う場面:

  • すべてを捨てて、完全に過去の状態に戻りたい
  • 実験的な変更を全部削除したい

何が起こる:

  • コミット履歴 → 1つ前に戻る
  • ステージングエリア → 空になる
  • ワーキングツリー → 変更が消える(元に戻せない!)

実践例:直前のコミットをやり直す

シナリオ: さっきコミットしたけど、ファイルを1つ追加し忘れた!

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

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

# 3. 改めてコミット
git commit -m "正しいコミット"

これで、きれいな履歴のまま修正完了です!

特定のコミットに戻る方法

直前だけでなく、もっと前のコミットにも戻れます。

まず、コミット履歴を確認:

git log --oneline

出力例:

a1b2c3d (HEAD) 最新のコミット
e4f5g6h バグ修正を試みた
i7j8k9l 新機能を追加
m1n2o3p 初期実装

例えば、「新機能を追加」の時点に戻りたい場合:

# コミットハッシュを指定
git reset --hard i7j8k9l

または、HEADからの相対位置で指定:

# 2つ前のコミットに戻る
git reset --hard HEAD~2

HEAD~1、HEAD~2って何?

  • HEAD = 今いる場所(最新のコミット)
  • HEAD~1 = 1つ前のコミット
  • HEAD~2 = 2つ前のコミット
  • HEAD~3 = 3つ前のコミット

^(キャレット)も使えます:

  • HEAD^ = HEAD~1と同じ
  • HEAD^^ = HEAD~2と同じ

git revert:安全に取り消す

git revertは、指定したコミットの変更を打ち消す新しいコミットを作成します。

なぜ revert を使うの?

履歴を書き換えないため、チーム開発で安全です。

例えるなら:

  • reset = 日記を破って捨てる → 他の人が混乱
  • revert = 「昨日のは間違いでした」と新しく書く → みんな理解できる

基本的な使い方

# 直前のコミットを取り消す
git revert HEAD

エディタが開いてコミットメッセージを聞かれるので、適当に書いて保存します。

すると、こんな感じの新しいコミットが作られます:

a1b2c3d Revert "バグ修正を試みた"
e4f5g6h バグ修正を試みた
i7j8k9l 新機能を追加

メッセージなしで revert

git revert HEAD --no-edit

--no-editをつけると、デフォルトのメッセージでコミットされます。

特定のコミットを revert

# コミットハッシュを指定
git revert e4f5g6h

これで、e4f5g6hのコミットだけが取り消されます。

複数のコミットを revert

# 範囲指定(古い方..新しい方)
git revert 古いハッシュ..新しいハッシュ

例:

git revert HEAD~3..HEAD

マージコミットの revert

マージコミットを revert する場合は、-mオプションが必要です:

# 1番目の親を残す
git revert -m 1 マージコミットのハッシュ

実践例:プッシュ済みのバグを修正

シナリオ: さっきプッシュしたコミットにバグがあった!みんなもpullしちゃってる…

# 1. 履歴を確認
git log --oneline

# 2. 問題のコミットをrevert
git revert バグのあるコミットハッシュ

# 3. リモートにプッシュ(普通のpushでOK)
git push origin main

これで、他のメンバーも普通にgit pullするだけで修正が取り込まれます!

git checkout / git switch:過去を覗く

git checkoutgit switchを使うと、過去のコミットの状態を一時的に見ることができます。

注意:Git 2.23以降の変更

Git 2.23から、役割が分離されました:

  • git switch = ブランチの切り替え専用
  • git restore = ファイルの復元専用
  • git checkout = 両方できる(古い方法)

新しいGitでは、git switchgit restoreを使うことが推奨されています。

過去のコミットを確認する

# 過去のコミットに移動
git checkout コミットハッシュ

または(新しい方法):

git switch --detach コミットハッシュ

これで、そのコミット時点のファイルの状態が見られます。

「detached HEAD」状態って何?

過去のコミットに移動すると、こんな警告が出ます:

You are in 'detached HEAD' state.

これは、ブランチから外れた状態という意味です。

detached HEAD状態でできること:

  • ファイルを見る ✅
  • コードを実行してテストする ✅
  • 新しくコミットする ⚠️(注意が必要)

戻り方:

# 元のブランチに戻る
git checkout main

または:

git switch main

実践例:バグがいつ混入したか調査

シナリオ: 今バグがあるけど、昔は動いてた。いつから壊れたんだろう?

# 1. 履歴を確認
git log --oneline

# 2. 怪しいコミットに移動
git checkout 過去のコミットハッシュ

# 3. テストする
npm test  # または、手動でテスト

# 4. 問題なければ、もっと新しいコミットを試す
git checkout もう少し新しいコミット

# 5. 原因が分かったら、元に戻る
git checkout main

過去の状態で新しいブランチを作る

過去の状態から作業を始めたい場合:

# 過去のコミットに移動
git checkout 過去のコミット

# そこから新しいブランチを作成
git checkout -b 新しいブランチ名

または(新しい方法):

git switch -c 新しいブランチ名 過去のコミット

これで、安全に過去の状態から作業を開始できます!

git restore:ファイルを復元する

Git 2.23以降で追加された、ファイルの復元専用コマンドです。

特定のファイルだけを過去に戻す

# ワーキングツリーのファイルを復元
git restore ファイル名

これで、まだコミットしていない変更が破棄されます。

特定のコミットからファイルを復元

# 特定のコミットの状態に戻す
git restore --source=コミットハッシュ ファイル名

ステージングを取り消す

# git add を取り消す
git restore --staged ファイル名

実践例:1つのファイルだけ過去に戻す

シナリオ: config.jsだけ、2つ前のコミットの状態に戻したい

# 1. どのコミットに戻すか確認
git log --oneline config.js

# 2. 特定のコミットから復元
git restore --source=HEAD~2 config.js

# 3. 確認
git status

# 4. コミット
git add config.js
git commit -m "config.jsを過去の状態に戻す"

古い方法(git checkout)との比較

古い方法:

git checkout HEAD~2 -- config.js

新しい方法:

git restore --source=HEAD~2 config.js

機能は同じですが、git restoreの方が明示的で分かりやすいです。

間違えた!取り消した resetを取り消す方法

git reset --hardしちゃったけど、やっぱり元に戻したい…」

大丈夫です。git reflogが助けてくれます!

git reflog:Gitの履歴の履歴

git reflogは、HEADの移動履歴を記録しています。

git reflog

出力例:

a1b2c3d HEAD@{0}: reset: moving to HEAD~1
e4f5g6h HEAD@{1}: commit: バグ修正
i7j8k9l HEAD@{2}: commit: 新機能追加

reset前の状態に戻る

# reset前のコミットに戻る
git reset --hard HEAD@{1}

または、コミットハッシュを指定:

git reset --hard e4f5g6h

これで、git reset --hardで消したコミットも復活します!

注意:reflogには期限がある

git reflogの記録は、デフォルトで90日間保存されます。それ以降は本当に消えてしまうので、早めに対処しましょう。

リモートにプッシュする方法

revert の場合(簡単!)

git revertは新しいコミットを作るだけなので、普通にプッシュできます:

git push origin main

reset の場合(注意が必要!)

git resetで履歴を書き換えた場合、普通にプッシュしようとするとエラーになります:

git push origin main
# エラー: Updates were rejected because the tip of your current branch is behind...

強制プッシュが必要:

git push --force origin main

⚠️ 超重要な注意:

強制プッシュは他のメンバーの作業を壊す可能性があります!

  • チーム開発では基本的に使わない
  • 使う場合は必ず事前にチームに連絡
  • 個人ブランチでのみ使う

より安全な強制プッシュ

git push --force-with-lease origin main

--force-with-leaseは、リモートが期待通りの状態の時だけプッシュします。誰かが先にプッシュしていたら失敗するので、より安全です。

状況別:どのコマンドを使うべき?

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

git commit --amend -m "正しいメッセージ"

(これが一番簡単!)

ケース2:直前のコミットにファイルを追加したい

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

# 直前のコミットに追加
git commit --amend --no-edit

ケース3:まだプッシュしてないコミットを取り消したい

# 変更は残す
git reset --soft HEAD~1

# 変更も消す
git reset --hard HEAD~1

ケース4:プッシュ済みのコミットを取り消したい

# revert を使う(安全)
git revert コミットハッシュ

# プッシュ
git push origin main

ケース5:過去のバージョンを確認したい

# 一時的に移動
git checkout コミットハッシュ

# 確認が終わったら戻る
git checkout main

ケース6:特定のファイルだけを過去に戻したい

# ファイルを復元
git restore --source=コミットハッシュ ファイル名

# コミット
git add ファイル名
git commit -m "ファイルを復元"

ケース7:間違えてファイルを削除してしまった

# 最後のコミットから復元
git restore ファイル名

ケース8:git addを取り消したい

# ステージングを取り消す
git restore --staged ファイル名

よくある質問(Q&A)

Q1:reset と revert、どっちを使えばいい?

A:プッシュしたかどうかで判断してください。

  • プッシュしてない → reset(履歴を書き換えてOK)
  • プッシュ済み → revert(安全に取り消し)

Q2:reset –hard で消したファイル、復元できる?

A:コミットしていれば、reflogから復元できます。

# 履歴を確認
git reflog

# reset前に戻る
git reset --hard HEAD@{1}

ただし、コミットしていない変更は復元できません

Q3:複数のコミットをまとめて取り消したい

A:範囲を指定できます。

reset の場合:

# 3つ前まで戻る
git reset --hard HEAD~3

revert の場合:

# 複数のコミットをrevert
git revert HEAD~2..HEAD

Q4:特定のコミットだけを取り消したい(間のコミットは残す)

A:revert を使います。

# 特定のコミットだけrevert
git revert 取り消したいコミットハッシュ

reset は「そこまで戻る」ですが、revert は「そのコミットだけ取り消す」ができます。

Q5:detached HEAD状態で作業しちゃった…

A:ブランチを作れば保存できます。

# 今の状態でブランチを作成
git switch -c 新しいブランチ名

これで、作業が保存されます。

Q6:リモートのコミットを強制的に元に戻したい

A:できますが、チームに大きな影響があります。

# ローカルで reset
git reset --hard 戻したいコミット

# 強制プッシュ(危険!)
git push --force origin main

絶対に実行前に:

  • チーム全員に連絡
  • 影響を確認
  • バックアップを取る

まとめ:コマンド早見表

状況コマンド安全性
直前のコミットメッセージ修正git commit --amend🟢 安全
プッシュしてないコミット取り消しgit reset --soft HEAD~1🟢 安全
変更も消してコミット取り消しgit reset --hard HEAD~1🔴 危険
プッシュ済みコミット取り消しgit revert HEAD🟢 安全
過去の確認だけgit checkout コミット🟢 安全
ファイルだけ復元git restore --source コミット ファイル🟢 安全
git addを取り消しgit restore --staged ファイル🟢 安全

重要ポイント

✅ 安全な方法:

  • git revert(履歴を保持)
  • git checkout(見るだけ)
  • git restore(ファイル単位)

⚠️ 注意が必要:

  • git reset –mixed(変更は残る)
  • git reset –soft(変更は残る)

🔴 危険な方法:

  • git reset –hard(変更が消える)
  • git push –force(他の人に影響)

おわりに:失敗を恐れずに

Gitの素晴らしいところは、ほとんどの失敗が取り返せることです。

  • git reset --hardしてしまった → git reflogで復元
  • 間違えてrevertした → もう一度revert
  • 変なブランチで作業しちゃった → git cherry-pickで移動

「間違えたらどうしよう…」と怖がるより、「間違えても大丈夫」と思って使いましょう!

困ったら:

  1. git statusで現状確認
  2. git logで履歴確認
  3. git reflogで最後の手段

この3つのコマンドが、あなたを助けてくれます。

Happy Git Life! 🚀

コメント

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