git reset --hardで消してしまったコミットは、多くの場合「git reflog」で復元できます。Gitは、HEADやブランチが指していた位置の履歴を記録していて、消えたように見えるコミットも、実体はしばらくリポジトリの中に残っているからです。

ただし、一度もコミットしていない変更は、reset --hardで消えると基本的に戻りません。この記事では、まず落ち着いて確認すべきこと、状況別の復元手順、そして次から焦らないための習慣までを解説します。

まず、やってはいけないこと

復元の前に、次の操作は避けてください。消えたコミットの手がかりが減る可能性があります。

  • git gc や git prune を実行する(到達できないコミットが掃除される)
  • 焦って別の reset や checkout を何度も重ねる(reflogが読みにくくなる)

まず git reflog を見る。 これだけで大半の状況は解決に向かいます。

git reflogとは

reflogは、HEAD(とブランチ)がどのコミットを指していたかの記録です。コミット、reset、checkout、rebase、mergeなど、HEADが動くたびに1行ずつ追加されます。

git reflog
a1b2c3d HEAD@{0}: reset: moving to HEAD~3
e4f5g6h HEAD@{1}: commit: ログイン画面のバリデーションを追加
i7j8k9l HEAD@{2}: commit: APIのエラーハンドリングを修正
...

HEAD@{1} は「1つ前にHEADが指していた場所」という意味です。reset直前の状態は、たいてい HEAD@{1} にあります。

reflogはローカルの記録で、既定では到達できなくなったコミットの記録は30日、それ以外は90日保持されます(gc.reflogExpireUnreachable / gc.reflogExpire)。気づいたら早めに復元するのが安全です。

状況別の復元手順

ケース1:reset --hardの直後に取り消したい

reset直後なら、ORIG_HEAD が直前の位置を覚えています。

git reset --hard ORIG_HEAD

ORIG_HEADは、reset・rebase・mergeなどの「HEADを大きく動かす操作」の直前の位置です。直後であれば、これが一番手軽です。

ケース2:少し前のresetを取り消したい

reflogで戻したい時点を探し、そこへresetします。

git reflog
# 戻したい行(例: HEAD@{3})を確認して
git reset --hard HEAD@{3}

いきなりresetするのが不安なら、まずブランチを作って保護するのがおすすめです。

git branch rescue HEAD@{3}
git log rescue      # 中身を確認してから

ブランチとして残しておけば、その後どう操作しても消えません。

ケース3:削除したブランチを復元したい

git reflog
# 削除したブランチの最後のコミットを探す(checkoutやcommitの記録から)
git branch 復元するブランチ名 <コミットのハッシュ>

git branch -D の直後であれば、削除時のメッセージに「Deleted branch xxx (was 1a2b3c4).」とハッシュが表示されているので、それをそのまま使えます。

ケース4:rebaseを取り消したい

rebase直後なら ORIG_HEAD にrebase前の位置が残っています。

git reset --hard ORIG_HEAD

時間が経っている場合は、reflogで rebase (start) の直前の行を探し、その位置へ戻します。

git reflog
# 「rebase (start)」より1つ下(古い側)の行が、rebase前の状態
git reset --hard HEAD@{n}

ケース5:消したstashを復元したい

git stash drop や git stash clear で消したstashは、reflogには残りませんが、到達できないコミットとして残っていることがあります。

git fsck --unreachable | grep commit
# 表示されたハッシュを1つずつ確認
git show <ハッシュ>
# 目的のものが見つかったら
git stash apply <ハッシュ>

stashを消した直後なら、ターミナルに表示された「Dropped refs/stash@{0} (ハッシュ)」のハッシュでそのまま git stash apply できます。

push済みの場合は「reset」ではなく「revert」

すでにリモートにpushしたコミットを取り消したい場合、resetして強制pushするのは避けるのが原則です。他のメンバーが取り込んだ履歴と食い違い、チームの作業を壊してしまうことがあります。

git revert <取り消したいコミット>

revertは、「打ち消すコミット」を新しく追加するので、履歴を書き換えずに変更を取り消せます。共有ブランチでは、これが安全な方法です。

どうしても強制pushが必要な場合は、--force ではなく --force-with-lease を使います。自分が最後に確認した後に誰かがpushしていたら失敗してくれるので、他人の作業を上書きする事故を防げます。

復元できないケース

  • 一度もコミットもステージもしていない変更 — reset --hardで消えた作業ツリーの変更は、Gitの記録に残っていないため復元できません。エディタのローカル履歴機能(IDEの履歴)が最後の頼みです
  • ステージ(git add)だけした変更 — コミットはしていなくても、git fsck --lost-found でファイルの中身(blob)が見つかる場合があります
  • reflogの保持期間が過ぎ、gcで掃除された後 — 時間が経つほど復元は難しくなります

reset --soft / --mixed / --hardの違い

そもそもの理解として、resetには3つのモードがあります。

オプション HEAD(履歴) ステージ 作業ツリー(ファイル)
--soft 戻る そのまま そのまま
--mixed(既定) 戻る 戻る そのまま
--hard 戻る 戻る 戻る(変更が消える)

「コミットをやり直したいだけ」なら、--soft や --mixed で十分なことがほとんどです。作業ツリーの変更まで消すのは --hard だけなので、使う前に一度立ち止まる習慣が事故を減らします。

次から焦らないための習慣

  • 危険な操作の前にブランチを1本作る — git branch backup-before-rebase の1行で、どう失敗しても戻れます
  • 作業途中でもこまめにコミットする — コミットさえしていれば、reflogで取り戻せます
  • --hardより先に git status と git stash — 消していいか迷う変更は、stashに退避してから操作する
  • 強制pushは --force-with-lease を習慣に

よくある質問

Q. reflogは他の人のリポジトリでも見られますか? A. 見られません。reflogはローカルの記録なので、自分のクローンにしかありません。他の人が消したコミットは、その人の環境のreflogで復元してもらう必要があります。

Q. reset --hardで消したファイルの変更(未コミット)は本当に戻りませんか? A. Gitの機能では戻りません。ステージ済みなら git fsck --lost-found で中身が見つかる場合があります。エディタやIDEのローカル履歴も確認してください。

Q. resetとrevertはどう使い分けますか? A. 自分のローカルだけにあるコミットならreset、共有ブランチにpush済みのコミットならrevertです。

Q. reflogはいつまで残りますか? A. 既定では、到達できなくなったコミットの記録は30日、それ以外は90日です。設定で変更できますが、気づいたら早めに復元してください。

まとめ

  • reset --hardで消えたコミットは、まず git reflog。直後なら git reset --hard ORIG_HEAD
  • 不安なら、復元先に ブランチを作って保護してから確認する
  • 削除したブランチ・rebase・stashも、reflogやfsckで多くの場合復元できる
  • push済みなら revert、強制pushは --force-with-lease
  • 未コミットの変更だけは戻らない。こまめなコミットが最大の保険

Gitは、コミットしたものを簡単には手放さない道具です。仕組みを知っておくと、rebaseもresetも怖くなくなります。株式会社RJCでは、こうした日々の開発の知識をチームで共有しながら、保険・金融・決済などのシステム開発に携わっています。

▶ RJC丸わかり https://www.r-jc.jp/guide/?mediacode=02-00001-003

▶ エントリーはこちら(1〜2分で完了します) https://www.r-jc.jp/recruitment/?mediacode=02-00001-003

株式会社RJC ― SI事業・SES事業・AI駆動開発。未経験からエンジニアに育てるのが得意な会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?