はじめに
現在、プログラミングスクールでWEBエンジニア転職を目指して学習中なのですが、プログラミングで避けては通れないものの一つにGitがあります。初学者であれば、そんな重要なGitを使用中にうっかりやらかしてしまうことも多いのではないでしょうか。
今回はgit reset --hard
でリセットしたコミットを実行後に元に戻す方法について紹介します。
忙しい方の為の超概要
やらかした人😇『ワァ、、、』
某ネコ🐈『間違えてhardモードで、resetしちゃったってコト!?』
某サイヤ人🦍『でぇじょうぶだ、reflog と reset コマンドで生きけぇれる』
対象者
- プログラミング初学者の方
注意 前提として、変更の取り消しに使用する git reset コマンドを理解している体で進めるので git reset コマンドの詳細な説明は割愛させていただきます。
git reset --hard
インデックスとワークツリーをリセットします。 以降のワークツリー内の追跡ファイルへの変更はすべて破棄されます。(Git コマンドリファレンス(日本語版)引用)
タイトルにある通り、--hard オプションで reset しても元に戻せます。
注意 ただしコミットしている場合に限ります!
後述する git reflog コマンドはHEADポインタの移動履歴を参照して表示するのですが、コミットされていない変更(ワーキングディレクトリやステージングエリアにある未コミットの変更)は参照・表示できません。git reset --hard
を実行するとコミットしていない変更は削除されるので、git reflog
とgit reset
を使ってもこれらの変更を元に戻せないためコミットしている必要があります。
現在の状態
現在、5つのコミットがある状態です。
$ git log --oneline
b7fef5e (HEAD -> main) Bakutan_R_kun
e1cdb3c Fall_in_love
b418c51 Flog
b3ce313 Fox
5bd80c8 Big_Bang
コミットを以前の状態に戻す
HEAD から2つ前のコミット(b418c51 Flog)に戻したいと仮定して、git reset --hard HEAD~2 を実行。コミットが2つ取り消されました。
$ git reset --hard HEAD~2
HEAD is now at b418c51 Flog
$ git log --oneline
b418c51 (HEAD -> main) Flog
b3ce313 Fox
5bd80c8 Big_Bang
その後、やっぱりコミットを取り消さなければよかった、、、
元に戻したい…!
git reflog と git reset --hard で解決 (本題)
元に戻したい…!となった際も、git reset --hard
を使用します。
--hard の後ろにコミットIDを指定する必要がありますが、git logコマンドでは現在あるコミットしか表示されないため、先にgit reflog コマンドを使用します。
git reflog
reflog(参照ログ)とは HEAD やブランチ先端の動きの履歴
各個人のローカルリポジトリに存在
ブランチの切り替え、新たに加えられた変更のプル、履歴の書き換え、あるいは単なる新規コミットの実行などを記録
git reflog で HEAD の移動履歴を、git reflog <ブランチ名> でそのブランチ先端が指していたコミットの一覧を確認可能。(下記サイトより引用)
reflogコマンドを実行すると、一番上のログにreset: moving to HEAD~2とあります。これがgit reset --hard
を実行した際のログなので、これを実行する一つ前のコミットIDであるb7fef5eを指定すれば良さそうです。
(reflog は、reference log の略)
$ git reflog
b418c51 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
b7fef5e HEAD@{1}: commit: Bakutan_R_kun #←このコミットIDを指定
e1cdb3c HEAD@{2}: commit: Fall_in_love
b418c51 (HEAD -> main) HEAD@{3}: commit: Flog
b3ce313 HEAD@{4}: commit: Fox
5bd80c8 HEAD@{5}: commit (initial): Big_Bang
コミットIDであるb7fef5eを指定してgit reset --hard
を実行
git reset --hard b7fef5e
HEAD is now at b7fef5e Bakutan_R_kun
ログを確認すると、無事元に戻せています💡
git log --oneline
b7fef5e (HEAD -> main) Bakutan_R_kun #←復活
e1cdb3c Fall_in_love #←復活
b418c51 Flog
b3ce313 Fox
5bd80c8 Big_Bang
最後に
Gitの記録は全てルートディレクトリに存在する.gitディレクトリで管理されています。もし .git ディレクトリを消してしまった場合は(ローカルの変更履歴が失われるため)元には戻せません…!
また今回のケースとは異なりますが、git reflog
はマージしていないブランチを削除してしまった際などにも有効です。
何か誤りがあればコメント等でご指摘いただけますと幸いです。