Git Reset 101 – Hacker Noon

Now that we have that covered we can finally go to our reset command and see how it works by manipulating the content of these git areas (trees).

reset — soft

This first mode of reset command will only do one thing:

  • move the HEAD pointer

In our case, we will move it to the previous commit (the first version of index.php) by runing:

git reset --soft HEAD~1

The trees of git now look like this:

And when we run git status we see a familiar message:

Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified:   index.php

So, running git reset — soft HEAD~1 has basically undone our last commit, but the changes contained in that commit are not lost — they are in our Staging Area and Working Directory.

reset — mixed

The second mode of reset command will do two things:

  • move the HEAD pointer
  • update the Staging Area (with the content that the HEAD is pointing to)

So, the first step is the same as with the--soft mode. The second step takes whatever the HEAD points to ( in this case, it is version one of the index.php file) and puts it into the Staging Area.

So, after running git reset --mixed HEAD~1 our areas look like this:

And running git status now again gives us a familiar message:

Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified:   index.php

So, running git reset — mixed HEAD~1 has undone our last commit, but this time the changes from that commit are (only) in our Working Directory.

reset — hard

And now for the notorious hard mode. Running reset — hard will do three things:

  • move the HEAD pointer
  • update the Staging Area (with the content that the HEAD is pointing to)
  • update the Working Directory to match the Staging Area

So, the first two steps are the same as with--mixed.The third makes the Working Directory look like the Staging Area (that was already filled with what HEAD is pointing to).

So, after running git reset --hard HEAD~1 our areas look like this:

And running git status gives us:

nothing to commit, working tree clean

So, running git reset — hard HEAD~1 has undone our last commit and the changes contained in that commit are neither in our Working Directory or the Staging Area. But they are not completely lost. Git doesn’t delete commits from Repository (actually, it does sometimes, but very rarely), so this means our commit with the second version is still in the Repository, it is just a bit hard to find (you can track it by looking at something called reflog).

So, what is then with this reputation of reset being dangerous? Well, there is one case where some changes could be permanently lost. Consider a scenario where after the second commit you make some more changes to your index.php file, but you don’t stage and commit them:

And now you run git reset --hard HEAD~1 :

Since the reset --hard overwrites the content of your Working Directory to match the Staging Area (that is already made to match HEAD) and you never staged and committed your changes so there is no commit with those changes in the repository, all those changes will now be lost in time… Like tears in the rain.

The danger of hard reset lies in the fact that it is not Working Directory safe — meaning it won’t give you any warning if you have file changes in your Working Directory that will be overwritten (and lost) if you run it. So be (extra) careful with a hard reset.

read original article here