Undo a hard reset with reference log

We can undo a hard reset with git reflog.

After we do a hard reset, we can’t see the changes of that commit in git log or working directory anymore. But still we can use reflog to rescue recently deleted commits.

$ git reflog
  7e603f6 HEAD@{0}: reset: moving to HEAD^
  29738b4 HEAD@{1}: commit: Test something.
  7e603f6 HEAD@{2}: reset: moving to HEAD^
  85f5fe2 HEAD@{3}: commit: Test something.
  7e603f6 HEAD@{4}: reset: moving to HEAD^
  ac7adcb HEAD@{5}: commit: Test something.
  7e603f6 HEAD@{6}: reset: moving to HEAD^
  4a4ab6e HEAD@{7}: commit: Ignore dot_git.
  7e603f6 HEAD@{8}: reset: moving to HEAD^
  d2bb180 HEAD@{9}: commit: Add dot_git folder to let student resume my working directory status.
  7e603f6 HEAD@{10}: reset: moving to HEAD^
  c366c68 HEAD@{11}: commit: Add dot_git to ignore list.
  7e603f6 HEAD@{12}: commit (merge): Merge github/master
  988b280 HEAD@{13}: commit: Add a call to action text.
  39b246b HEAD@{14}: checkout: moving from bbb771688b6ff5a0f114b0e36820e117a8f78736 to master
  bbb7716 HEAD@{15}: checkout: moving from master to github/master
  39b246b HEAD@{16}: commit: Add logo and links in HTML.
  8527471 HEAD@{17}: merge index_b: Fast-forward
  8e6852d HEAD@{18}: checkout: moving from index_b to master
  8527471 HEAD@{19}: commit (merge): Merge 'index_a'
  5b1bad2 HEAD@{20}: commit: Change text in HTML.
  8e6852d HEAD@{21}: checkout: moving from master to index_b
  8e6852d HEAD@{22}: checkout: moving from index_a to master
  f9fca5f HEAD@{23}: commit: Add year to footer copyright.
  8e6852d HEAD@{24}: checkout: moving from master to index_a
  8e6852d HEAD@{25}: commit: Add tags to HTML file.
  5d8c653 HEAD@{26}: reset: moving to 5d8c653
  0da344e HEAD@{27}: commit (amend): Add footer tag.
  ee60e93 HEAD@{28}: commit: Add fotter tag.
  66c7c85 HEAD@{29}: commit: Add <p> tag to paragraphs.
  46953e0 HEAD@{30}: commit: Add header tag.
  5d8c653 HEAD@{31}: reset: moving to HEAD~1
  7d0439b HEAD@{32}: commit: Quick commit

From the reflog, we can see the hash ID of deleted commits.

Then we can create a new branch by picking that hash.

$ git checkout -b rescue_branch HASH_ID

At this moment, we create a branch that points to the deleted commit. Next, we can simply merge the working branch, e.g. master, to the rescue_branch and done.

At last, we can clean up the repo by deleting the temporary rescue_branch.

$ git branch -d rescue_branch