2017年08月05日

git 失敗したときの復元

コミットしたけど間違っていたので無かったことにしたいと思えば git reset が使うことで履歴を変更できる。きれいさっぱり消して戻してくれる。
が、もしリセットする箇所を間違えたらどうなるのか?

このようなコミット履歴があった場合に、
$ git log --oneline
827142f modified2 a.txt b.txt
e379d74 modified a.txt b.txt
6c5004e modified a.txt d.txt
069d76c Add file :d.txt
4bfcd75 modified c.txt
3f062b7 modified b.txt
9925985 modified a.txt
d79bc0b Add files


間違ってコミットしたので、"HEAD^" で1つ前に戻ることにした。
$ git reset --hard HEAD^^
HEAD is now at 6c5004e modified a.txt d.txt

操作をミスで、"HEAD^^" で戻し過ぎてしまった!
reset --hard なのできれいに無くなってしまった!!
途方に暮れてしまう場面だが、gitにはこんなときでも復旧手段がある。




reflog(参照ログ)で復旧


$ git reflog


"reflog" はすべての変更を記録してくれている。
$ git reflog
6c5004e HEAD@{0}: reset: moving to HEAD^^
827142f HEAD@{1}: commit: modified2 a.txt b.txt
e379d74 HEAD@{2}: commit: modified a.txt b.txt
6c5004e HEAD@{3}: commit: modified a.txt d.txt
069d76c HEAD@{4}: commit: Add file :d.txt
4bfcd75 HEAD@{5}: commit: modified c.txt
3f062b7 HEAD@{6}: commit: modified b.txt
9925985 HEAD@{7}: commit: modified a.txt
d79bc0b HEAD@{8}: commit (initial): Add files


今回であれば git reset --hard HEAD^^ の前に戻れば復旧できるので、"HEAD@{1}" にリセットする。

$ git reset --hard HEAD@{1}


コミット履歴を確認してみる。
$ git log --oneline
827142f modified2 a.txt b.txt
e379d74 modified a.txt b.txt
6c5004e modified a.txt d.txt
069d76c Add file :d.txt
4bfcd75 modified c.txt
3f062b7 modified b.txt
9925985 modified a.txt
d79bc0b Add files

途方に暮れてしまう前の状態に巻き戻すことができている!


git reset だけではなく、git rebaseブランチの付け替えに失敗したときや、履歴の変更したときも使える。あとは、"detached HEAD" 状態に気づかずにコミットした後で、ブランチを切り替えた場合に、見えなくなってしまったコミットIDを探してチェリーピックすれば、失われたコミットをサルベージすることができる。




まとめ


作業ツリー上にしか存在していなかったデータなどはコミットしていなければ戻すことはできないが、直近の内容でコミットさえしてあれば、データがどこかに残っているので、目の前からデータが消えるようなことになってもリカバリできる。ただ、過去にさかのぼるのも限界があるので、間違いには早めに気づいて、気づいたらすぐに対処するのが良い。






gitをインストール
gitサーバーのセットアップ
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git リモートブランチを追加
git チェックアウトをもっと便利に使う
git プロジェクトの構成
git 変更をpatchファイルにする
git コンフリクトに対処する
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする