無料プレビュー 5 / 14

間違えた時の取り消し方 — restore, reset, revert

学習目標

このレッスンを終えると、次のことができるようになります。

  • restore / reset / revert の使い分けを表で説明できる
  • 「push 済」と「push 前」で取り消し方が変わる理由を理解できる
  • git reflog で「うっかり消した commit」を救出できる

取り消しの 3 段階

Git の取り消し操作は どこまで進んだ作業を戻すか によって違う。

flowchart LR W[作業ディレクトリ<br/>編集中] -->|git add| S[ステージング エリア] S -->|git commit| L[ローカル リポジトリ] L -->|git push| R[リモート<br/>GitHub] W -.戻す.-> R1[git restore] S -.戻す.-> R2[git restore --staged] L -.戻す.-> R3[git reset] R -.戻す.-> R4[git revert]
状態 取り消しコマンド 戻せる範囲
編集したがまだ add してない git restore <ファイル> 編集をなかったことに
add したがまだ commit してない git restore --staged <ファイル> ステージから降ろす (編集は残る)
commit したがまだ push してない git reset HEAD~1 commit を取り消す (ローカル安全)
push してしまった git revert <ハッシュ> 打ち消し commit を新たに作る (履歴は残す)

ケース 1: 編集を破棄したい (まだ add 前)

# src/login.py を編集したが、やっぱり元に戻したい
git restore src/login.py

注意: 編集内容は完全消去。Ctrl+Z できない。事前に git diff で内容を確認してから実行する。

ケース 2: ステージから降ろしたい (add したけど commit する前)

git add src/login.py        # add した
# やっぱりこの変更は次の commit に入れたくない
git restore --staged src/login.py
# → ステージから降りる。編集自体は残っている (作業ディレクトリにある)

ケース 3: commit を取り消したい (まだ push してない)

git log --oneline
# a1b2c3d (HEAD) fix: ログイン修正    ← これを取り消したい
# 9f8e7d6 feat: 検索機能追加

git reset HEAD~1
# → a1b2c3d の commit を解いて、編集内容は作業ディレクトリに戻る

reset の 3 モード

モード 効果 いつ使う
--soft commit だけ解く。編集はステージング エリアに残る commit メッセージだけ書き直したい
--mixed (デフォルト) commit と add を解く。編集は作業ディレクトリに残る commit 分け直したい
--hard commit・add・編集すべて消す。復元不可 完全になかったことにしたい (危険)

⚠️ --hard は破壊的。本講座 01-02 の「人間が必須」操作。AI Agent に単独実行させない。

ケース 4: push 済の変更を打ち消す (revert)

# すでに push 済の a1b2c3d を打ち消したい
git revert a1b2c3d
# → 「a1b2c3d を打ち消す内容」の新規 commit が作られる
git push

revert は 履歴を消さず、打ち消し commit を追加する。他人がすでにその commit をベースに作業していてもトラブルにならない。

gitGraph commit id: "init" commit id: "9f8e7d6: 検索追加" commit id: "a1b2c3d: ログイン修正" commit id: "Revert: ログイン修正"

なぜ push 済を reset で消してはいけないか

git reset + git push --force でリモート履歴を書き換えると:

  • 他のメンバーが既にその commit をベースに作業していた場合、全員の履歴が壊れる
  • GitHub Actions / CI が混乱する
  • リリースタグが指す commit が消えて本番デプロイ履歴が追えなくなる

→ 公開済の commit は revert で打ち消す。これが鉄則。

救出: git reflog — 消したと思った commit を取り戻す

git reset --hard で消したコミットも、約 90 日間は .git/ 内部に残っている。

git reflog
# 出力例:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~1
# d4e5f6a HEAD@{1}: commit: 大事な変更
# ...

# d4e5f6a を復元したい
git reset --hard d4e5f6a

reflog は「あなた自身がやった操作の履歴」。事故った時の最終救出ツール。まず焦って何かする前に git reflog を見る。

取り消し選択フロー

flowchart TD Q[何かを取り消したい] --> P{push 済?} P -->|No| L{commit 済?} P -->|Yes| V[git revert で打ち消し commit] L -->|No| A{add 済?} L -->|Yes| R[git reset で戻す] A -->|No| D[git restore で編集破棄] A -->|Yes| U[git restore --staged で降ろす] R -.失敗で消した?.-> RF[git reflog で救出]

振り返り

  • 取り消しは 「進んだ段階」によってコマンドが変わる
  • push 済は revert (履歴を残して打ち消し)。reset + force push は禁忌
  • git reflog は最後の救出策。事故ったらまず深呼吸して reflog を見る

次のセクションから、本コースの中心である branch (枝分かれ) と merge (統合) を学びます。

参考リンク

全 14 レッスンを、登録なしで無料で読めます。