【Git】git reset --hard HEADを取り消したい!!
こんにちは、マリンです。
今日Gitでやらかしました。
表題の通りなのですが、それにプラスしてDBのロールバックとかも関わってきて、
「ギャーーーー!!!」
ってなったので残しておきます。
概要
やらかした内容が多すぎるので、時系列で箇条書きします。
新規でDBのテーブルを作成するのに
rails g migration ~~
で作ってしまった。テーブルを作った後しばらく作業を進めてからModelが無いことに気づく。(この間何度かcommitしてる)
Modelだけ作れば良いところ、わざわざ
rake db:rollback
しようとした。だがロールバックする前に何を思ったかCommitをテーブル作る以前まで戻してしまった。
しかもGitの取り消しを
git reset --hard HEAD@{n}
でやってしまった。(ここが一番問題)
やはり一番のやらかしポイントは、commitのやり直しで
git reset --hard HEAD@{n}
を使ってしまったことでしょう。
--hard
オプションをつけると、ワーキングツリーまで変更されてします。
では、これに対する対処を次から書いていきます。
対処法
1、2、3まではおそらくModelファイルだけ作ってあげれば良かった話だと思うので省略します。
4、5、6について詳細と対処法を記載しようと思います。
そもそも何が起こったのか?
私が不用意に打ったgit reset --hard HEAD@{n}
これによって何が起こったのかを解説します。
飛ばしていただいて結構です。
$ git reset --hard HEAD^
git reset
:これは任意のcommitを取り消すコマンドです。--hard
:resetコマンドのオプションです。コミットだけでなく、ワーキングツリーまで元の状態に書き換えます。HEAD@{n}
:HEADの位置をどこまで戻すかを指示しています。@{n}
で遡ることn番目のcommitを表します。
問題は真ん中の--hard
オプションです。
これによりワーキングツリーまで元の状態に戻ってしまったため、
テーブル作成のために書いたマイグレーションファイルまで消えてしまいました。
(今回はテーブル作成をする一つ前のコミットまで戻ったので・・・)
そしてこれをrake db:rollback
を実行する前にやってしまいました。
該当のマイグレーションファイルが無いのにロールバックしたってできるわけがありません。
なのでこの取り消し(git reset)を取り消して、マイグレーションファイルを復活させる!
それが今回の目標です。
ちなみに問題のオプションですが、
--soft
にを指定すればコミットだけをなかったことにしてくれます。
これにしていればアワアワすることもなかったでしょう・・・
他にもコミットとインデックスを取り消す--mixed
もあります。
オプション無しのデフォルトもこれです。
こちらでより詳しく説明してくださっています。
[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法
コミット取り消しの取り消し
ここからが本題です。
消してしまった事実をなかったことにして、
マイグレーションファイルを復活させます。
$ git reflog $ git reset --hard HEAD@{n} $ git log
こちらが一連の流れです。
git reflog
:
まずどこまでコミットを戻すか履歴を見ます。
コマンドがgit log
でない理由は、
リセットされたコミットはgit log
の履歴に出てこないからです。
git reflog
は消されたコミットも履歴として見ることができます。
git reset --hard HEAD@{n}
:
ここで取り消しを無かったことにします。
今回は--hard
オプションで大丈夫です。
消えてしまったワーキングツリーのファイルを復活させたいので。
HEAD@{n}
のnにはログで確認した該当コミットが現在地から何番目にあたるかの番号を入れてください。
reflog
の時に番号入りで表示されるはずなのでわかりやすいと思います!
git log
:
最後に念のため確認をしましょう。
この場合はこちらの履歴で大丈夫です。
以上が解説になります。
なお、実例を交えたより詳しい説明をこちらでしてくださっていますので、
ぜひご覧ください。
git reset --hardした内容を取り消す (git reset --hard, reflog, HEAD@{x}, 取り消してしまったコミットを元に戻す) - いろいろ備忘録日記
まとめ
今までadd、commit、pushくらいしかやってこなかったGitです。
正直他のことはよくわからないから触りたく無かったし、
そもそも何ができるのかも曖昧でした。
しかし、今回初めて「履歴が残っている」ということの有り難みを感じました。
そしてむやみに手元まで変えてはならない!!ということも・・・
基本は--soft
でやるのが安全だし、一般的な様ですね。
大変勉強になりました!