In one of my earliest posts, I wrote an introduction to version control, more specifically: git. The topic I will cover today extends this article by a topic which is actually not that complicated. However, people seem to find it hard to deal with it and use it as a highway to StackOverflow.
I talk about git reset. This command can be used to reset changes in your working area or to remove staged files from the index. I think that one of the problems here is the context-dependent functionality of the command. Another problem is the commands potentially disruptive character, since it can lead to data loss.
Moving the current Branch
In general, you can split the commands functionality into two separate parts. First, the command will move the current branch. Let's look at an example. In my current project, I've made some changes that I'd like to reset. In my example, my current commit 25a5d0e contains unwanted information and I'd like to return back to the state at commit ea02e01.
Of course, this is a very simple example, git reset is not restricted to a single branch. I'd also like to mention, that this operation will lead to commits that don't belong to any branch. In this case, git will automatically detect and delete them using its garbage collection mechanism.
As I mentioned earlier, the reset command moves the current branch (which is actually a pointer to a specific commit). The second part of its functionality is to optionally copy contents from the repository to the index (also known as staging area) and the working area.
To specify where contents should be copied to, you can use the parameters -hard, -mixed or -soft. First of these copies the contents from the repository to both the index, and the working area. Appending -mixed will lead to the contents being copied only to the index, not to the working area. When using git reset without any parameters, this is what will be applied. The last option is to use -soft, which will prevent any content from being copied. In this case, only the branch-movement-part of the command will be executed.
Working with git reset is easier than you think. Also, it's definitely helpful to always think of the two components. Doing so, there is another a really cool feature that you may already have seen: You can use git reset to unstage files. Alternatively to git rm -cached, you can use git reset HEAD -mixed, which will overwrite the staged files.